1

I've created a simple program that uses a thread to parse through a log file and print a value. After reading up on creating detached threads, I made the thread detached and destroyed the attribute (PTHREAD_CREATE_DETACHED) afterwards in my main function. I also exited the thread (not exiting created even more memory leaks). However, I still have memory leaks and an error, even though I'm pretty sure that I don't malloc anything in the rest of the program. Here is the full code:

*Credits go to Jonathan Leffler for the strtok_fixed function which parses a delimited string

static char *strtok_fixed(char *str, char const *delims)
{
    static char  *src = NULL;
    char  *p,  *ret = 0;

    if (str != NULL)
        src = str;

    if (src == NULL || *src == '\0')    // Fix 1
        return NULL;

    ret = src;                          // Fix 2
    if ((p = strpbrk(src, delims)) != NULL)
    {
        *p  = 0;
        //ret = src;                    // Unnecessary
        src = ++p;
    }
    else
        src += strlen(src);

    return ret;
}

void * parse_log(void *arguments){

    file = fopen("oms_requests.log", "r");
    char c;

    if (file == NULL){                        //no valid file
        printf("couldn't find the file\n");
    } else {
        int f = fseek(file, -2, SEEK_END);
        if (f == 0){
            int counter = 1;
            c = fgetc(file);
            while (c != '\n'){
                counter++;
                fseek(file, -counter, SEEK_END);
                c = fgetc(file);
            }

            //now read last line in the log into buff 
            char buff[counter];
            int l = fread(buff, 1, counter, file);
            buff[counter-1] = '\0';

            if (l != counter-1){
                printf("counter is wrong\n");
            } else {
                //skip over 22 commas to get the value that I want 
                char *buffer = strtok_fixed(buff, ",");
                for (int i = 0; i < 22; i++){
                    buffer = strtok_fixed(NULL, ",");
                    if (buffer == '\0') i++;
                        printf("%s\n", buffer);
                    }
                    printf("%ld\n", strtol(buffer, NULL, 10));
                }
        } else {
            printf("error in getting to bottom of file\n");
        }
    }
    fclose(file);
}


int main(int argc, char *argv[])
{
    //create pthread attributes and set to detached 
    pthread_t thr;
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

    int l = pthread_create(&thr, &attr, parse_log, NULL);
    if (l != 0){
        printf("Didn't work\n");
        return -1;
    }

    //destroy pthread attribute and exit 
    pthread_attr_destroy(&attr);
    pthread_exit(&thr);
    return 0;
}

Here is the report given by valgrind when I run the program:

==12387== HEAP SUMMARY:
==12387==     in use at exit: 272 bytes in 1 blocks
==12387==   total heap usage: 7 allocs, 6 frees, 2,510 bytes allocated
==12387==
==12387== Searching for pointers to 1 not-freed blocks
==12387== Checked 8,486,312 bytes
==12387==
==12387== 272 bytes in 1 blocks are possibly lost in loss record 1 of 1
==12387==    at 0x4C2CC70: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12387==    by 0x4012E54: _dl_allocate_tls (dl-tls.c:296)
==12387==    by 0x4E3FDA0: pthread_create@@GLIBC_2.2.5 (allocatestack.c:589)
==12387==    by 0x400E11: main (in /afs/.ir.stanford.edu/users/d/i/dianale/CS107/assign1a/reassemble)
==12387==
==12387== LEAK SUMMARY:
==12387==    definitely lost: 0 bytes in 0 blocks
==12387==    indirectly lost: 0 bytes in 0 blocks
==12387==      possibly lost: 272 bytes in 1 blocks
==12387==    still reachable: 0 bytes in 0 blocks
==12387==         suppressed: 0 bytes in 0 blocks
==12387==
==12387== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

I've also tried pthread_detach(&thr) instead of setting an attribute (I've also tried having both at the same time), but I still get the exact same memory leaks and errors. Is there any way to fix this?

Community
  • 1
  • 1
ddkle
  • 21
  • 6
  • How do you compile this? Do you use the gcc option `-pthread` or "just" link using `-lpthread`?? – alk Jul 16 '15 at 06:42
  • Also what is the idea behind passing `thr` here `pthread_exit(&thr);`? – alk Jul 16 '15 at 06:43
  • I specifically write `gcc -pthread -std=c99 -o file file.c` in the command line when I compile and I don't get any errors or warnings. I also thought that I needed to specify the exact thread that I wanted to exit in `pthread_exit` so I placed &thr in there. I've also tried doing `pthread_exit(NULL)` and gotten the exact same memory errors/leaks. – ddkle Jul 16 '15 at 16:28
  • Always compile with all warning's on. To do so with gcc specifiy `-Wall -Wextra -pedantic`. Also you might like to take a look into `pthread_exit()`'s documentation to learn what the parameter is used for. Guessing is a bad option ... really. – alk Jul 16 '15 at 16:36
  • Thanks for the tip about the warnings! I got rid of all of the warnings, and I've read the pthread_exit() documentation. Based on my understanding, adding a `return NULL` at the bottom of my parse_log function should implicitly call pthread_exit() on thr and end the thread. I think pthread_exit is supposed to be used when you may have a thread waiting on the status of a child thread, and the pthread_exit ends the child thread, making it available to the parent. So, I added `return NULL` and removed `pthread_exit()`, but I get even more leaks. Am I misunderstanding something? – ddkle Jul 16 '15 at 17:30
  • @alk the program also doesn't return the expected value. – ddkle Jul 16 '15 at 17:37

1 Answers1

0

Pthreads allocates certain amount of memory for maintaining each thread's internal state. Detaching a thread only marks that those resources can be reclaimed immediately after the thread exits (as opposed to holding the state in case some other thread might need it). Butt these resources will remain allocated until the thread completes execution. Valgrind might report them as possible "leak".

Also remember that valgrind reports false positives at times. I don't see anything obvious in your code that could lead to leaks either. So I wouldn't worry about those "possible leaks" message.

P.P
  • 117,907
  • 20
  • 175
  • 238
  • The error is still a bit unsettling though; this suggests that I'm writing into something that I shouldn't. Can this also be ignored? – ddkle Jul 15 '15 at 22:31
  • If this is the code that produces those warnings then yes, I would ignore it. There's nothing I can see that could leak. – P.P Jul 15 '15 at 22:33