Date: Mon, 15 Jan 2001 05:08:57 -0800 (PST) From: fishkin@port.ru To: freebsd-gnats-submit@FreeBSD.org Subject: misc/24345: pthread library libc_r causes memory leak at termination of joinable thread Message-ID: <200101151308.f0FD8v470958@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 24345 >Category: misc >Synopsis: pthread library libc_r causes memory leak at termination of joinable thread >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Mon Jan 15 05:10:01 PST 2001 >Closed-Date: >Last-Modified: >Originator: Andy Fedotov >Release: 3.5-STABLE, 4.1-STABLE >Organization: Port.RU, Inc. >Environment: FreeBSD xxxxxx.xxx.xxxx.xx 3.5-STABLE FreeBSD 3.5-STABLE #0: Tue Jan 9 13:49:27 MSK 2001 root@xxxxxx.xxx.xxxx.xx:/usr/src/sys/compile/HELL i386 FreeBSD xxx.xxxxx 4.1-STABLE FreeBSD 4.1-STABLE #3: Thu Nov 30 21:00:56 MSK 2000 root@xxx.xxxxx:/usr/src/sys/compile/MAC i386 >Description: Garbage collector looks into list of dead threads and freeing resources only for threads with PTHREAD_DETACHED flag. Unfortunattely pthread_join() doesn't set PTHREAD_DETACHED flag on thread after fetching it return value. So, garbage collector leave this thread in dead list and won't free() any resources associated with it. This causes memory leak. >How-To-Repeat: Simply start thread in joinable state, and then join on it. ------ #ifndef _THREAD_SAFE #define _THREAD_SAFE #endif #ifndef _REENTRANT #define _REENTRANT #endif #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <pthread.h> unsigned long brk_value = 0; void *check_leak(void *arg) { unsigned long current_brk = (unsigned long) sbrk(0); if (current_brk > brk_value) if (brk_value != 0) fprintf(stdout, "Data segment grows up by 0x%lX bytes\n", current_brk - brk_value); brk_value = current_brk; pthread_exit(NULL); } int main() { pthread_t tid; pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); for (;;) { if (pthread_create(&tid, &attr, check_leak, NULL)) { perror("pthread_create"); exit(0); } else pthread_join(tid, NULL); } } ----- >Fix: Should we simply set PTHREAD_DETACHED flag after sucessfuly joining on thread ? But this is not solution for pthread_cancel(), that also put threads in dead list w/o PTHREAD_DETACHED flag set. --- uthread_join.c.orig Mon Jan 15 15:11:30 2001 +++ uthread_join.c Mon Jan 15 15:12:34 2001 @@ -117,6 +117,8 @@ /* Return the thread's return value: */ *thread_return = pthread->ret; + pthread->attr.flags |= PTHREAD_DETACHED; + _thread_leave_cancellation_point(); /* Return the completion status: */ >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200101151308.f0FD8v470958>