threads/166932: sleepqueue-related memory leak in libthr

Dmitry Marakasov amdmi3 at FreeBSD.org
Fri Apr 13 23:50:13 UTC 2012


>Number:         166932
>Category:       threads
>Synopsis:       sleepqueue-related memory leak in libthr
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-threads
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Apr 13 23:50:12 UTC 2012
>Closed-Date:
>Last-Modified:
>Originator:     Dmitry Marakasov
>Release:        FreeBSD 9.0-RELEASE amd64
>Organization:
>Environment:
System: FreeBSD hades.panopticon 9.0-RELEASE FreeBSD 9.0-RELEASE #0: Tue Jan 10 01:33:18 MSK 2012 root at hades.panopticon:/usr/obj/usr/src/sys/HADES amd64


>Description:
Seems like there's a memory leak in libthr when threads are created and joined continously.

See attached program. It creates and joins 16 threads, and repeats that multiple times.
If LOOPS = 1, there's no leak regardless of how many threads are created.
If LOOPS > 1, there's a leak of 64 bytes per each created thread. With 1024 loops it's approx. 1MB which is visible in valgrind output:

==41498== HEAP SUMMARY:
==41498==     in use at exit: 1,065,912 bytes in 16,402 blocks
==41498==   total heap usage: 16,403 allocs, 1 frees, 1,065,992 bytes allocated
==41498== 
==41498== Searching for pointers to 16,402 not-freed blocks
==41498== Checked 34,403,992 bytes
==41498== 
==41498== 1,047,552 bytes in 16,368 blocks are definitely lost in loss record 5 of 5
==41498==    at 0x1004654: calloc (in /usr/local/lib/valgrind/vgpreload_memcheck-amd64-freebsd.so)
==41498==    by 0x12166A5: _sleepq_alloc (in /lib/libthr.so.3)
==41498==    by 0x121A497: _thr_alloc (in /lib/libthr.so.3)
==41498==    by 0x121311D: pthread_create (in /lib/libthr.so.3)
==41498==    by 0x400673: main (in /tmp/a.out)
==41498== 
==41498== LEAK SUMMARY:
==41498==    definitely lost: 1,047,552 bytes in 16,368 blocks
==41498==    indirectly lost: 0 bytes in 0 blocks
==41498==      possibly lost: 0 bytes in 0 blocks
==41498==    still reachable: 18,360 bytes in 34 blocks
==41498==         suppressed: 0 bytes in 0 blocks

And if LOOPS is set to some value high enough (say, 102400), the leak may be seen with naked eye (process eats over 140MB as seen in top).

>How-To-Repeat:
#include <pthread.h>

#define LOOPS 1024
#define THREADS 16

void* threadfunc(void* arg) {
    return NULL;
}

int main() {
    int loop, thread;
    pthread_t threads[THREADS];
    for (loop = 0; loop < LOOPS; ++loop) {
        for (thread = 0; thread < THREADS; ++thread)
            pthread_create(&threads[thread], NULL, threadfunc, NULL);
        for (thread = 0; thread < THREADS; ++thread)
            pthread_join(threads[thread], NULL);
    }

    return 0;
}
>Fix:

>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-threads mailing list