0

This is what I get from valgrind:

==1654036== Thread 102:
==1654036== Invalid read of size 1
==1654036==    at 0x491328C: _IO_file_fopen@@GLIBC_2.2.5 (fileops.c:225)
==1654036==    by 0x4905B0D: __fopen_internal (iofopen.c:75)
==1654036==    by 0x4905B0D: fopen@@GLIBC_2.2.5 (iofopen.c:86)
==1654036==    by 0x10A9EC: readFromDisk (in /home/john/OS4061/p3/group/p3/web_server)
==1654036==    by 0x10AC72: worker (in /home/john/OS4061/p3/group/p3/web_server)
==1654036==    by 0x4866608: start_thread (pthread_create.c:477)
==1654036==    by 0x49A2292: clone (clone.S:95)
==1654036==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==1654036== 
==1654036== 
==1654036== Process terminating with default action of signal 11 (SIGSEGV)
==1654036==  Access not within mapped region at address 0x0
==1654036==    at 0x491328C: _IO_file_fopen@@GLIBC_2.2.5 (fileops.c:225)
==1654036==    by 0x4905B0D: __fopen_internal (iofopen.c:75)
==1654036==    by 0x4905B0D: fopen@@GLIBC_2.2.5 (iofopen.c:86)
==1654036==    by 0x10A9EC: readFromDisk (in /home/john/OS4061/p3/group/p3/web_server)
==1654036==    by 0x10AC72: worker (in /home/john/OS4061/p3/group/p3/web_server)
==1654036==    by 0x4866608: start_thread (pthread_create.c:477)
==1654036==    by 0x49A2292: clone (clone.S:95)

And here is the function

int readFromDisk(char *mybuf, char *request) {
    int num_bytes = 0;
    FILE *file = fopen(request, O_RDONLY);
        if(file == NULL){
                return 0;
        }
        
    while(fread(mybuf,1, 1, file)!=EOF){
        num_bytes++;
    }
    return num_bytes;
}

I have tried printing request and it is a valid file path.

Thank you in advance.

3 Answers3

2

Others have pointed out the problem with O_RDONLY being a valid value for open (not fopen), also

while(fread(mybuf,1, 1, file)!=EOF){

is not what you want.

The return value of fread:

The total number of elements successfully read is returned. If this number differs from the count parameter, either a reading error occurred or the end-of-file was reached while reading. In both cases, the proper indicator is set, which can be checked with ferror and feof, respectively. If either size or count is zero, the function returns zero and both the stream state and the content pointed by ptr remain unchanged. size_t is an unsigned integral type.

Switch to:

while(fread(mybuf,1, 1, file)==1){

And always prefer size_t when returning the size of a file

size_t readFromDisk(char *mybuf, char *request) {
    size_t num_bytes = 0;
    ...

EDIT 1:

Now I'm getting an invalid read for fread, any ideas there?

Better ask the system, add this outside the while loop:

    if (ferror(file))
    {
        perror("fread");
        return 0;
    }

and you may receive a hint, if you don't receive any hint you can try with explain_fread:

The explain_fread function is used to obtain an explanation of an error returned by the fread(3) system call. The least the message will contain is the value of strerror(errno), but usually it will do much better, and indicate the underlying cause in more detail.

EDIT 2:

I also see (from the output of valgrind) that you are developing or using a web server, it is very likely that the error is not in fread but in the buffer that stores the content, surely valgrind is so vague and imprecise in the output due to (as pointed out by @KrishnaKanthYenumulayou in comments) the omission of the -g flag in the compilation.

David Ranieri
  • 39,972
  • 7
  • 52
  • 94
1
==1654036==  Address 0x0 is not stack'd, malloc'd or (recently) free'd

You are passing a NULL pointer to fopen. As per the comments and other answer, this is from O_RDONLY

/usr/include/sys/fcntl.h:#define    O_RDONLY    0
Paul Floyd
  • 5,530
  • 5
  • 29
  • 43
1

Change this line

FILE *file = fopen(request, O_RDONLY);

to

FILE *file = fopen(request, "r");

That way, fopen() can succeed (if everything else is correct).

wallyk
  • 56,922
  • 16
  • 83
  • 148