0

I am modifying some http server code, and this is a function for sending file or list of directory. I keep getting this error which suggest a memory problem :

    *** Error in `./a.out': free(): invalid next size (fast): 
    0x08b85200 ***
    ======= Backtrace: =========
    /usr/lib/libc.so.6(+0x69923)[0xb7677923]
    /usr/lib/libc.so.6(+0x6fc47)[0xb767dc47]
    /usr/lib/libc.so.6(+0x70401)[0xb767e401]
    ./a.out[0x8049093]
    ./a.out[0x8049455]
    ./a.out[0x804952d]
    ./a.out[0x804964e]
    /usr/lib/libc.so.6(__libc_start_main+0xf7)[0xb7626497]
    ./a.out[0x8048a51]
    ======= Memory map: ========
    08048000-0804a000 r-xp 00000000 08:01 3147464    /home/baroc/Desktop/HW3/part3/a.out
    0804a000-0804b000 rw-p 00001000 08:01 3147464    /home/baroc/Desktop/HW3/part3/a.out
    08b85000-08ba6000 rw-p 00000000 00:00 0          [heap]
    b7400000-b7421000 rw-p 00000000 00:00 0 
    b7421000-b7500000 ---p 00000000 00:00 0 
    b75df000-b75fb000 r-xp 00000000 08:01 1183170    /usr/lib/libgcc_s.so.1
    b75fb000-b75fc000 rw-p 0001b000 08:01 1183170    /usr/lib/libgcc_s.so.1
    b760d000-b760e000 rw-p 00000000 00:00 0 
    b760e000-b77c1000 r-xp 00000000 08:01 1182850    /usr/lib/libc-2.22.so
    b77c1000-b77c2000 ---p 001b3000 08:01 1182850    /usr/lib/libc-2.22.so
    b77c2000-b77c4000 r--p 001b3000 08:01 1182850    /usr/lib/libc-2.22.so
    b77c4000-b77c5000 rw-p 001b5000 08:01 1182850    /usr/lib/libc-2.22.so
    b77c5000-b77c8000 rw-p 00000000 00:00 0 
    b77d7000-b77d9000 rw-p 00000000 00:00 0 
    b77d9000-b77da000 rw-p 00000000 00:00 0 
    b77da000-b77dc000 r--p 00000000 00:00 0          [vvar]
    b77dc000-b77dd000 r-xp 00000000 00:00 0          [vdso]
    b77dd000-b77ff000 r-xp 00000000 08:01 1182848    /usr/lib/ld-2.22.so
    b77ff000-b7800000 r--p 00021000 08:01 1182848    /usr/lib/ld-2.22.so
    b7800000-b7801000 rw-p 00022000 08:01 1182848    /usr/lib/ld-2.22.so
    bfc06000-bfc27000 rw-p 00000000 00:00 0          [stack]

Here is my code:

    static int handleFileRequest(
            const char *webRoot, const char *requestURI, int clntSock)
    {

        int statusCode;
        FILE *fp = NULL;
        char *file = (char *)malloc(strlen(webRoot) + strlen(requestURI) + 100);

        if (file == NULL)
            die("malloc failed");
        strcpy(file, webRoot);
        strcat(file, requestURI);
        struct stat st;
        if (file[strlen(file)-1] == '/') {
            char *tfile = (char *)malloc(strlen(file));
            strcpy(tfile, file);
            strcat(tfile,"index.html");
            if(stat(tfile, &st) != 0){
                int fd[2];
                pid_t pid;
                if(pipe(fd)<0)
                    die("pipe() failed when list dir");
                if((pid = fork())<0){
                    die("fork failed when list dir");
                }else if(pid>0){
                    close(fd[0]);
                    if(fd[1]!=STDOUT_FILENO){
                        if(dup2(fd[1],STDOUT_FILENO)!=STDOUT_FILENO)
                            die("dup2 error to stdout");
                    }
                    close(fd[1]);
                    if(execl("/bin/ls", "ls", file, NULL)<0)
                        die("error execl ls");
                    close(fd[1]);
                    if(waitpid(pid, NULL, 0)<0){
                        die("waitpid error");
                    }
                    exit(0);
                }else{
                    close(fd[1]);
                    int n;
                    char wline[DISK_IO_BUF_SIZE];
                    while ((n = read(fd[0], wline, sizeof(wline))) > 0) {
                        if (send(clntSock, wline, n, 0) != n) {
                            perror("\nsend() failed");
                            break;
                        }
                    }
                    close(fd[0]);
                    exit(0);
                }

                free(tfile);
                goto func_end;
            }else{
                strcat(file, "index.html");
                free(tfile);
            }
        }
        //change this part for identifying a directory

        if (stat(file, &st) == 0 && S_ISDIR(st.st_mode)) {
            statusCode = 403; // "Forbidden"
            sendStatusLine(clntSock, statusCode);
            goto func_end;
        }
        fp = fopen(file, "rb");

        if (fp == NULL) {
            statusCode = 404; // "Not Found"
            sendStatusLine(clntSock, statusCode);
            goto func_end;
        }
        statusCode = 200; // "OK"
        sendStatusLine(clntSock, statusCode);
        size_t n;
        char buf[DISK_IO_BUF_SIZE];
        while ((n = fread(buf, 1, sizeof(buf), fp)) > 0) {
            if (send(clntSock, buf, n, 0) != n) {
                perror("\nsend() failed");
                break;
            }
        }
        if (ferror(fp))
            perror("fread failed");
    func_end:
        // clean up
        free(file);
        if (fp)
            fclose(fp);
        return statusCode;
    }

The problem occurs when I try to access a directory with "index.html" in it. like /test/, where has /test/index.html

It seems that the problem is with the "free(file);" at the end of the code. When I comment it out, there is no error when run on my Mac, but still error on linux. I don't understand where I did it wrong. Plz someone help me!


I used valgrind as suggested, and this is what I got:

    --1936-- REDIR: 0x40ba300 (libc.so.6:malloc) redirected to 0x402a129 (malloc)
    --1936-- REDIR: 0x40c0060 (libc.so.6:__GI_memchr) redirected to 0x402e100 (__GI_memchr)
    --1936-- REDIR: 0x40c0d50 (libc.so.6:__GI_memcpy) redirected to 0x402ea20 (__GI_memcpy)
    ==1936== embedded gdbserver: reading from /tmp/vgdb-pipe-from-vgdb-to-1936-by-baroc-on-???
    ==1936== embedded gdbserver: writing to   /tmp/vgdb-pipe-to-vgdb-from-1936-by-baroc-on-???
    ==1936== embedded gdbserver: shared mem   /tmp/vgdb-pipe-shared-mem-vgdb-1936-by-baroc-on-???
    ==1936== 
    ==1936== TO CONTROL THIS PROCESS USING vgdb (which you probably
    ==1936== don't want to do, unless you know exactly what you're doing,
    ==1936== or are doing some strange experiment):
    ==1936==   /usr/lib/valgrind/../../bin/vgdb --pid=1936 ...command...
    ==1936== 
    ==1936== TO DEBUG THIS PROCESS USING GDB: start GDB like this
    ==1936==   /path/to/gdb ./a.out
    ==1936== and then give GDB the following command
    ==1936==   target remote | /usr/lib/valgrind/../../bin/vgdb --pid=1936
    ==1936== --pid is optional if only one valgrind process is running
    ==1936== 
    --1936-- REDIR: 0x40be450 (libc.so.6:strcmp) redirected to 0x402555d (_vgnU_ifunc_wrapper)
    --1936-- REDIR: 0x417e340 (libc.so.6:__strcmp_ssse3) redirected to 0x402de80 (strcmp)
    --1936-- REDIR: 0x40beb20 (libc.so.6:strlen) redirected to 0x402555d (_vgnU_ifunc_wrapper)
    --1936-- REDIR: 0x40c7c80 (libc.so.6:__strlen_sse2_bsf) redirected to 0x402cda0 (strlen)
    --1936-- REDIR: 0x40bf970 (libc.so.6:strstr) redirected to 0x4031220 (strstr)
    --1936-- REDIR: 0x40be510 (libc.so.6:strcpy) redirected to 0x402555d (_vgnU_ifunc_wrapper)
    --1936-- REDIR: 0x40c7e50 (libc.so.6:__strcpy_ssse3) redirected to 0x402ce80 (strcpy)
    --1936-- REDIR: 0x40be030 (libc.so.6:strcat) redirected to 0x402555d (_vgnU_ifunc_wrapper)
    --1936-- REDIR: 0x40d3410 (libc.so.6:__strcat_ssse3) redirected to 0x402ca60 (strcat)
    ==1936== Invalid write of size 1
    ==1936==    at 0x402CEC5: strcpy (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
    ==1936==    by 0x8048E63: handleFileRequest (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x804947E: doProcess (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049556: doFork (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049677: main (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==  Address 0x420229a is 0 bytes after a block of size 42 alloc'd
    ==1936==    at 0x402A1AE: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
    ==1936==    by 0x8048E4F: handleFileRequest (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x804947E: doProcess (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049556: doFork (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049677: main (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936== 
    ==1936== Invalid read of size 1
    ==1936==    at 0x8048E78: handleFileRequest (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x804947E: doProcess (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049556: doFork (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049677: main (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==  Address 0x420229a is 0 bytes after a block of size 42 alloc'd
    ==1936==    at 0x402A1AE: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
    ==1936==    by 0x8048E4F: handleFileRequest (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x804947E: doProcess (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049556: doFork (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049677: main (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936== 
    ==1936== Invalid write of size 4
    ==1936==    at 0x8048E86: handleFileRequest (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x804947E: doProcess (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049556: doFork (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049677: main (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==  Address 0x420229a is 0 bytes after a block of size 42 alloc'd
    ==1936==    at 0x402A1AE: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
    ==1936==    by 0x8048E4F: handleFileRequest (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x804947E: doProcess (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049556: doFork (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049677: main (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936== 
    ==1936== Invalid write of size 4
    ==1936==    at 0x8048E8C: handleFileRequest (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x804947E: doProcess (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049556: doFork (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049677: main (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==  Address 0x420229e is 4 bytes after a block of size 42 alloc'd
    ==1936==    at 0x402A1AE: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
    ==1936==    by 0x8048E4F: handleFileRequest (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x804947E: doProcess (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049556: doFork (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049677: main (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936== 
    ==1936== Invalid write of size 2
    ==1936==    at 0x8048E93: handleFileRequest (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x804947E: doProcess (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049556: doFork (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049677: main (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==  Address 0x42022a2 is 8 bytes after a block of size 42 alloc'd
    ==1936==    at 0x402A1AE: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
    ==1936==    by 0x8048E4F: handleFileRequest (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x804947E: doProcess (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049556: doFork (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049677: main (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936== 
    ==1936== Invalid write of size 1
    ==1936==    at 0x8048E99: handleFileRequest (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x804947E: doProcess (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049556: doFork (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049677: main (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==  Address 0x42022a4 is 10 bytes after a block of size 42 alloc'd
    ==1936==    at 0x402A1AE: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
    ==1936==    by 0x8048E4F: handleFileRequest (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x804947E: doProcess (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049556: doFork (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049677: main (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936== 
    ==1936== Syscall param stat64(file_name) points to unaddressable byte(s)
    ==1936==    at 0x411F42A: _xstat (in /usr/lib/libc-2.22.so)
    ==1936==    by 0x804970D: stat (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8048EAB: handleFileRequest (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x804947E: doProcess (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049556: doFork (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049677: main (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==  Address 0x420229a is 0 bytes after a block of size 42 alloc'd
    ==1936==    at 0x402A1AE: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
    ==1936==    by 0x8048E4F: handleFileRequest (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x804947E: doProcess (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049556: doFork (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049677: main (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936== 
    --1936-- REDIR: 0x40ba950 (libc.so.6:free) redirected to 0x402b101 (free)
    --1936-- REDIR: 0x40c2960 (libc.so.6:strchrnul) redirected to 0x4030bd0 (strchrnul)
    1936 127.0.0.1 "GET /test/test2/ HTTP/1.1" 200 OK
    ==1936== 
    ==1936== HEAP SUMMARY:
    ==1936==     in use at exit: 0 bytes in 0 blocks
    ==1936==   total heap usage: 4 allocs, 4 frees, 872 bytes allocated
    ==1936== 
    ==1936== All heap blocks were freed -- no leaks are possible
    ==1936== 
    ==1936== ERROR SUMMARY: 8 errors from 7 contexts (suppressed: 0 from 0)
    ==1936== 
    ==1936== 1 errors in context 1 of 7:
    ==1936== Syscall param stat64(file_name) points to unaddressable byte(s)
    ==1936==    at 0x411F42A: _xstat (in /usr/lib/libc-2.22.so)
    ==1936==    by 0x804970D: stat (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8048EAB: handleFileRequest (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x804947E: doProcess (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049556: doFork (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049677: main (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==  Address 0x420229a is 0 bytes after a block of size 42 alloc'd
    ==1936==    at 0x402A1AE: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
    ==1936==    by 0x8048E4F: handleFileRequest (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x804947E: doProcess (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049556: doFork (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049677: main (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936== 
    ==1936== 
    ==1936== 1 errors in context 2 of 7:
    ==1936== Invalid write of size 1
    ==1936==    at 0x8048E99: handleFileRequest (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x804947E: doProcess (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049556: doFork (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049677: main (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==  Address 0x42022a4 is 10 bytes after a block of size 42 alloc'd
    ==1936==    at 0x402A1AE: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
    ==1936==    by 0x8048E4F: handleFileRequest (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x804947E: doProcess (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049556: doFork (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049677: main (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936== 
    ==1936== 
    ==1936== 1 errors in context 3 of 7:
    ==1936== Invalid write of size 4
    ==1936==    at 0x8048E8C: handleFileRequest (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x804947E: doProcess (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049556: doFork (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049677: main (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==  Address 0x420229e is 4 bytes after a block of size 42 alloc'd
    ==1936==    at 0x402A1AE: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
    ==1936==    by 0x8048E4F: handleFileRequest (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x804947E: doProcess (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049556: doFork (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049677: main (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936== 
    ==1936== 
    ==1936== 1 errors in context 4 of 7:
    ==1936== Invalid write of size 4
    ==1936==    at 0x8048E86: handleFileRequest (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x804947E: doProcess (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049556: doFork (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049677: main (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==  Address 0x420229a is 0 bytes after a block of size 42 alloc'd
    ==1936==    at 0x402A1AE: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
    ==1936==    by 0x8048E4F: handleFileRequest (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x804947E: doProcess (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049556: doFork (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049677: main (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936== 
    ==1936== 
    ==1936== 1 errors in context 5 of 7:
    ==1936== Invalid read of size 1
    ==1936==    at 0x8048E78: handleFileRequest (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x804947E: doProcess (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049556: doFork (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049677: main (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==  Address 0x420229a is 0 bytes after a block of size 42 alloc'd
    ==1936==    at 0x402A1AE: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
    ==1936==    by 0x8048E4F: handleFileRequest (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x804947E: doProcess (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049556: doFork (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049677: main (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936== 
    ==1936== 
    ==1936== 1 errors in context 6 of 7:
    ==1936== Invalid write of size 1
    ==1936==    at 0x402CEC5: strcpy (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
    ==1936==    by 0x8048E63: handleFileRequest (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x804947E: doProcess (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049556: doFork (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049677: main (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==  Address 0x420229a is 0 bytes after a block of size 42 alloc'd
    ==1936==    at 0x402A1AE: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
    ==1936==    by 0x8048E4F: handleFileRequest (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x804947E: doProcess (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049556: doFork (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049677: main (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936== 
    ==1936== 
    ==1936== 2 errors in context 7 of 7:
    ==1936== Invalid write of size 2
    ==1936==    at 0x8048E93: handleFileRequest (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x804947E: doProcess (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049556: doFork (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049677: main (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==  Address 0x42022a2 is 8 bytes after a block of size 42 alloc'd
    ==1936==    at 0x402A1AE: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
    ==1936==    by 0x8048E4F: handleFileRequest (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x804947E: doProcess (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049556: doFork (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936==    by 0x8049677: main (in /home/baroc/Desktop/HW3/part3/a.out)
    ==1936== 
    ==1936== ERROR SUMMARY: 8 errors from 7 contexts (suppressed: 0 from 0)
Yuqing
  • 333
  • 3
  • 13
  • 5
    `char *tfile = (char *)malloc(strlen(file));` Size is insufficient. – BLUEPIXY Feb 24 '16 at 00:52
  • Looks like you smacked the control information for `file`'s memory allocation. Probably what @BLUEPIXY pointed out above, but maybe not. [I recommend running the program through valgrind](http://stackoverflow.com/questions/5134891/how-do-i-use-valgrind-to-find-memory-leaks) to see if there are any more nasty surprises. – user4581301 Feb 24 '16 at 00:57
  • 3
    C and C++ are distinct languages. DO not add both tags unles both are involved. Your code looks like C, but includes discouraged constructs, which would be required in C++, though. Pick **one** language! – too honest for this site Feb 24 '16 at 01:03
  • 3
    Please select one of either C or C++. They say [you shouldn't cast the result of `malloc()` in C](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). – MikeCAT Feb 24 '16 at 01:05
  • C != C++, just like *cat != car*. Just because they start with the same letter does not make them the same language. If you don't know which one you're using, step away from the keyboard until you figure it out, and then use the tag that is appropriate to your question. Tags have meaning here, and you should use only tags that are relevant to your question. If you read the description of the tag, it should become clear whether it applies; if you're not sure, don't use it. – Ken White Feb 24 '16 at 01:09
  • sorry about the tag, please forgive me for my lack of knowledge. Should I tag it C or C++? – Yuqing Feb 24 '16 at 01:25
  • Where are you checking the `strlen(file) > 0` before `char *tfile = (char *)malloc(strlen(file));`? If for some reason file is empty, you could run into trouble. You should also make that check before `file[strlen(file)-1` as well or you will invoke *undefined behavior*. That could be done by checking the length of `webRoot` and `requestURI` to insure they have characters. – David C. Rankin Feb 24 '16 at 04:56

1 Answers1

1
      ...
if (file[strlen(file)-1] == '/') {
            char *tfile = (char *)malloc(strlen(file));
            strcpy(tfile, file);
            strcat(tfile,"index.html");
      ...

tfile is allocated the same size as file's length. tfile gets everything in file, plus a null terminator one past the end of its allocation. tfile is concatenated with more stuff, further beyond its allocated capacity.

Christopher Oicles
  • 3,017
  • 16
  • 11
  • Should I use sizeof(file) instead of strlen(file), since the string file was originally allocated more memory. Or should I just malloc(strlen(file)+100). – Yuqing Feb 24 '16 at 01:23
  • You could try `strlen(file) + 1 + 10 + 100` (1 for the null, 10 for the length of "index.html" and 100 for good measure!) – Christopher Oicles Feb 24 '16 at 01:24
  • Thanks a lot! I will have a try! – Yuqing Feb 24 '16 at 01:27
  • Another question, what should I tag this problem? C or C++? I am confused. – Yuqing Feb 24 '16 at 01:58
  • Well, if you don't cast you `malloc`s to `(char*)`, does it compile without an error (like if you just put `char *file = malloc(strlen(...`)? If that works, then this is C, if you can't build because of some kind of error when you change that, then this is C++. – Christopher Oicles Feb 24 '16 at 02:10
  • If you switch the tag to C++, keep in mind that you will probably just end up being abused for not using std::string. – Christopher Oicles Feb 24 '16 at 02:19