Bug 71354 - STL / Pthreads - memory leaks
STL / Pthreads - memory leaks
Status: CLOSED NEXTRELEASE
Product: Red Hat Linux
Classification: Retired
Component: libstdc++ (Show other bugs)
7.3
i386 Linux
medium Severity high
: ---
: ---
Assigned To: Jakub Jelinek
http://bugzilla.redhat.com/bugzilla/s...
:
: 71292 (view as bug list)
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2002-08-12 13:27 EDT by Need Real Name
Modified: 2007-04-18 12:45 EDT (History)
0 users

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2004-10-01 20:01:09 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description Need Real Name 2002-08-12 13:27:29 EDT
From Bugzilla Helper:
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 4.0; Insight  - 
www.insight.com 1800-INSIGHT)

Description of problem:
Programs developed using STL strings, maps, vectors, etc. with pthreads 
causessevere memory leaks.


Version-Release number of selected component (if applicable):


How reproducible:
Always

Steps to Reproduce:
Here is a sample program that will always leak memory. It has been
tested using both GCC-2.9.6 and GCC-3.1.1 on RedHat Linux versions 6.2,
7.2, and 7.3. It has been tested using single and multi-processor
machines:


////////////////////////////////////////////////////////////////////
// BEGIN:  stl_leaker.cpp                                         //
////////////////////////////////////////////////////////////////////
#define _GNU_SOURCE
#define _REENTRANT
#define _THREAD_SAFE
#include <pthread.h>
#include <iostream>
#include <string>
#include <unistd.h>
using namespace std;

void *processClient(void *clientArgs);
pthread_attr_t attrDetached;

int main(int argc, char **argv) 
{
        int numThreads = 20;
        pthread_attr_init(&attrDetached);
        pthread_attr_setdetachstate(&attrDetached, PTHREAD_CREATE_DETACHED);
        pthread_t clientThread; //Threads are detached, don't care about
handle                  
        for ( int threadCount = 0; threadCount <= numThreads; threadCount++ ) {
                                
                if ( (pthread_create(&clientThread, &attrDetached, 
processClient,
(void *)NULL)) != 0 ) {
                        cout << endl << "ERROR: Could not create client
thread.";                                       
                        break; 
                }                                                       
        }
        sleep(10); //Make sure all detached threads have a chance to return     
        pthread_attr_destroy(&attrDetached);
        cout << endl << "DONE !" << endl;               
        return 0;
}

void *processClient(void *clientArgs) 
{       
        string s1, s2, s3, s4, s5, s6;
        s1.assign("blah123");
        s2.assign("blah123blah123");
        s3.assign("blah123blah123blah123");
        s4.assign("blah123blah123blah123blah123");
        s5.assign(s1 + s2);
        s6.assign(s3 + s2 + s1);        
        return NULL; 
}

////////////////////////////////////////////////////////////////////
// END: stl_leaker.cpp                                            //
////////////////////////////////////////////////////////////////////


This compile statement provides good debug output:

# g++ -g -DDEBUG stl_leaker.cpp -o stl_leaker -lpthread


Valgrind is an excellent, open-source tool for detecting memory leaks.
You can find it here  http://developer.kde.org/~sewardj/ .
Here is the command line for Valgrind that was used to detect the leak:

# valgrind --leak-check=yes --leak-resolution=high --num-callers=20
--show-reachable=yes --trace-children=yes -v ./stl_leaker


Actual Results:  The following is sample Valgrind output using the compile line
above. I
know for a fact these are not false positives. If configured to run a
long time, this program will keep snatching memory until there is none
left. Notice it always complains about line 490 in stl_alloc.h:
.
.
.
==4532== Reading suppressions file: /usr/local/lib/valgrind/default.supp
==4532== Reading syms from /home/sserv/stl_leaker
==4532== Reading syms from /lib/ld-2.2.4.so
==4532== Reading syms from /usr/local/lib/valgrind/valgrind.so
==4532== Reading syms from /usr/local/lib/valgrind/libpthread.so
==4532== Reading syms from /usr/lib/libstdc++-3-libc6.2-2-2.10.0.so
==4532== Reading syms from /lib/libm-2.2.4.so
==4532== Reading syms from /lib/libc-2.2.4.so
==4532== Estimated CPU clock rate is 300 MHz
==4532== 
valgrind's libpthread.so: IGNORED call to: pthread_attr_destroy
DONE !
valgrind's libpthread.so: libc_internal_tsd_get: dubious key 2
valgrind's libpthread.so: libc_internal_tsd_set: dubious key 2
valgrind's libpthread.so: libc_internal_tsd_get: dubious key 2
==4532== 
==4532== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 1 from 1)
--4532-- 
--4497-- supp:    1 __pthread_mutex_unlock/__register_frame_info
==4497== malloc/free: in use at exit: 4560 bytes in 2 blocks.
==4497== malloc/free: 23 allocs, 21 frees, 4812 bytes allocated.
==4497== 
==4497== searching for pointers to 2 not-freed blocks.
==4497== checked 4135240 bytes.
==4497== 
==4497== definitely lost: 0 bytes in 0 blocks.
==4497== possibly lost:   0 bytes in 0 blocks.
==4497== still reachable: 4560 bytes in 2 blocks.
==4497== 
==4497== 1280 bytes in 1 blocks are still reachable in loss record 1 of
2
==4497==    at 0x400457C4: malloc (vg_clientfuncs.c:100)
==4497==    by 0x804B147: ??? (/usr/include/g++-3/stl_alloc.h:490)
==4497==    by 0x804AF58: ??? (/usr/include/g++-3/stl_alloc.h:531)
==4497==    by 0x804AE82: ??? (/usr/include/g++-3/stl_alloc.h:419)
==4497==    by 0x804AD1C: ??? (/usr/include/g++-3/std/bastring.cc:33)
==4497==    by 0x804AAFE: ??? (/usr/include/g++-3/std/bastring.cc:60)
==4497==    by 0x804A93C: ??? (/usr/include/g++-3/std/bastring.cc:164)
==4497==    by 0x804A6CA: ??? (/usr/include/g++-3/std/bastring.h:223)
==4497==    by 0x804A558: ??? (/usr/include/g++-3/std/bastring.h:225)
==4497==    by 0x804A1B4: processClient(void *) (stl_leaker.cpp:37)
==4497==    by 0x40241166: thread_wrapper (vg_libpthread.c:521)
==4497==    by 0x4004A7FC: do__apply_in_new_thread_bogusRA
(vg_scheduler.c:2023)
==4497==    by 0x804A0DE: main (stl_leaker.cpp:28)
==4497==    by 0x402E5336: __libc_start_main
(../sysdeps/generic/libc-start.c:129)
==4497==    by 0x8049F61: pthread_mutex_unlock@@GLIBC_2.0 (in
/home/sserv/stl_leaker)
==4497== 
==4497== 3280 bytes in 1 blocks are still reachable in loss record 2 of
2
==4497==    at 0x400457C4: malloc (vg_clientfuncs.c:100)
==4497==    by 0x804B147: ??? (/usr/include/g++-3/stl_alloc.h:490)
==4497==   by 0x804AF58: ??? (/usr/include/g++-3/stl_alloc.h:531)
==4497==    by 0x804AE82: ??? (/usr/include/g++-3/stl_alloc.h:419)
==4497==    by 0x804AD1C: ??? (/usr/include/g++-3/std/bastring.cc:33)
==4497==    by 0x804AAFE: ??? (/usr/include/g++-3/std/bastring.cc:60)
==4497==    by 0x804A93C: ??? (/usr/include/g++-3/std/bastring.cc:164)
==4497==    by 0x804A7F5: ??? (/usr/include/g++-3/std/bastring.cc:131)
==4497==    by 0x804A730: ??? (/usr/include/g++-3/std/bastring.h:201)
==4497==    by 0x804A595: ??? (/usr/include/g++-3/std/bastring.h:480)
==4497==    by 0x804A25A: processClient(void *) (stl_leaker.cpp:42)
==4497==    by 0x40241166: thread_wrapper (vg_libpthread.c:521)
==4497==    by 0x4004A7FC: do__apply_in_new_thread_bogusRA
(vg_scheduler.c:2023)
==4497==    by 0x804A0DE: main (stl_leaker.cpp:28)
==4497==    by 0x402E5336: __libc_start_main
(../sysdeps/generic/libc-start.c:129)
==4497==    by 0x8049F61: pthread_mutex_unlock@@GLIBC_2.0 (in
/home/sserv/stl_leaker)
==4497== 
==4497== LEAK SUMMARY:
==4497==    definitely lost: 0 bytes in 0 blocks.
==4497==    possibly lost:   0 bytes in 0 blocks.
==4497==    still reachable: 4560 bytes in 2 blocks.
==4497== 
--4497--       lru: 0 epochs, 0 clearings.
--4497-- translate: new 1507 (23331 -> 307279), discard 0 (0 -> 0).
--4497--  dispatch: 0 basic blocks, 327/4209 sched events, 1539 tt_fast
misses.
--4497-- reg-alloc: 543 t-req-spill, 58421+3382 orig+spill uis, 7905
total-reg-r.
--4497--    sanity: 25 cheap, 1 expensive checks.


Expected Results:  No memory leaks should occur.


Additional info:

Thanks to anyone who helps this new programmer stay off the unemployment 
line. :-( Any help greatly appreciated.
Comment 1 Jakub Jelinek 2002-08-16 05:51:17 EDT
*** Bug 71292 has been marked as a duplicate of this bug. ***
Comment 2 Benjamin Kosnik 2004-10-01 20:01:09 EDT
Fixed gcc-3.2.x, gcc-3.3.x, gcc-3.4.x.

Note You need to log in before you can comment on or make changes to this bug.