From: Geoff A. <gal...@nc...> - 2003-04-01 04:45:45
|
In running valgrind 1.0.4 against a small program of mine, valgrind = reports "still reachable" memory at exit, both with g++ 2.95.2 and gcc = 3.2 on SuSE Linux x86 7.1. I've tracked the problem down to = std::string. Here's a small program that illustrates the problem: #include <cstdlib> #include <string> int main(int argc, char* argv[]) { { std::string s; s +=3D '0'; } exit(0); } Under g++ 2.95.2, valgrind reports: =3D=3D1214=3D=3D LEAK SUMMARY: =3D=3D1214=3D=3D definitely lost: 0 bytes in 0 blocks. =3D=3D1214=3D=3D possibly lost: 0 bytes in 0 blocks. =3D=3D1214=3D=3D still reachable: 1280 bytes in 1 blocks. and under g++ 3.2, valgrind reports: =3D=3D1236=3D=3D LEAK SUMMARY: =3D=3D1236=3D=3D definitely lost: 0 bytes in 0 blocks. =3D=3D1236=3D=3D possibly lost: 0 bytes in 0 blocks. =3D=3D1236=3D=3D still reachable: 640 bytes in 1 blocks. Note that the amount of memory report as "still reachable" grows larger = as more characters are appended to s. I suspect that the "still = reachable" memory is a static buffer allocated in std::string, rather = than leaked memory. Is this correct? If so, is there way to tell = valgrind not to report the memory allocated this std::string static = buffer.=20 Thanks, Geoff Alexander |
From: Jeremy F. <je...@go...> - 2003-04-01 06:31:52
|
On Mon, 2003-03-31 at 20:47, Geoff Alexander wrote: > In running valgrind 1.0.4 against a small program of mine, > valgrind reports "still reachable" memory at exit, both with g++ > 2.95.2 and gcc 3.2 on SuSE Linux x86 7.1. I've tracked the problem > down to std::string. Here's a small program that illustrates the > problem: > > #include <cstdlib> > #include <string> > int main(int argc, char* argv[]) > { > { > std::string s; > s += '0'; > } > exit(0); > } What happens if you return 0 rather than exit(0)? I'm not sure that s will necessarily have been destructed if you use exit. J |
From: Geoff A. <gal...@nc...> - 2003-04-02 04:34:17
|
----- Original Message -----=20 From: Jeremy Fitzhardinge=20 To: Geoff Alexander=20 Cc: val...@li...=20 Sent: Tuesday, April 01, 2003 1:31 AM Subject: Re: [Valgrind-users] "still reachable" memory from = g++'sstd::string On Mon, 2003-03-31 at 20:47, Geoff Alexander wrote:=20 In running valgrind 1.0.4 against a small program of mine, valgrind = reports "still reachable" memory at exit, both with g++ 2.95.2 and gcc = 3.2 on SuSE Linux x86 7.1. I've tracked the problem down to = std::string. Here's a small program that illustrates the problem:=20 #include <cstdlib> #include <string> int main(int argc, char* argv[]) { { std::string s; s +=3D '0'; } exit(0); }=20 What happens if you return 0 rather than exit(0)? I'm not sure that s = will necessarily have been destructed if you use exit.=20 J=20 Thanks for the suggestion. Using return 0 rather than exit(0) didn't = change anything. I verified under gdb that s is being destructed in = both cases. Geoff Alexander |
From: Maarten B. <maa...@mi...> - 2003-04-02 16:23:42
|
Hello, Just out of curiosity, why would s be destructed if you call exit()? I find it somewhat hard to believe (counter intuitive, even unwanted) that calling exit() from inside maybe a 10 level deep calling sequence would cause all stack based variables to be destructed? Thanks for any insights! Cheers, Maarten. On Tue, 2003-04-01 at 23:36, Geoff Alexander wrote: > > ----- Original Message ----- > From: Jeremy Fitzhardinge > To: Geoff Alexander > Cc: val...@li... > Sent: Tuesday, April 01, 2003 1:31 AM > Subject: Re: [Valgrind-users] "still reachable" memory from > g++'sstd::string > On Mon, 2003-03-31 at 20:47, Geoff Alexander wrote: > > In running valgrind 1.0.4 against a small program of mine, > > valgrind reports "still reachable" memory at exit, both with > > g++ 2.95.2 and gcc 3.2 on SuSE Linux x86 7.1. I've tracked > > the problem down to std::string. Here's a small program > > that illustrates the problem: > > #include <cstdlib> > > #include <string> > > int main(int argc, char* argv[]) > > { > > { > > std::string s; > > s += '0'; > > } > > exit(0); > > } > > What happens if you return 0 rather than exit(0)? I'm not > sure that s will necessarily have been destructed if you use > exit. > J > Thanks for the suggestion. Using return 0 rather than exit(0) didn't > change anything. I verified under gdb that s is being destructed in > both cases. > > Geoff Alexander -- Maarten Ballintijn <maa...@mi...> Massachusetts Institute of Technology |
From: Olly B. <ol...@su...> - 2003-04-02 16:35:55
|
On Wed, Apr 02, 2003 at 11:23:34AM -0500, Maarten Ballintijn wrote: > > > { > > > std::string s; > > > s += '0'; > > > } > > > exit(0); > Just out of curiosity, why would s be destructed if you call exit()? s is destructed at the end of the block where it's defined - i.e. the line before exit is called. Cheers, Olly |
From: Jeremy F. <je...@go...> - 2003-04-02 17:49:49
|
On Wed, 2003-04-02 at 08:34, Olly Betts wrote: > On Wed, Apr 02, 2003 at 11:23:34AM -0500, Maarten Ballintijn wrote: > > > > { > > > > std::string s; > > > > s += '0'; > > > > } > > > > exit(0); > > > Just out of curiosity, why would s be destructed if you call exit()? > > s is destructed at the end of the block where it's defined - i.e. the > line before exit is called. Do you mean the compiler is treating exit specially? Is that because its a noreturn function? That still can't be right: if it were a noreturn function which takes a std::string argument, then it would be wrong to destruct the string before passing it. J |
From: Olly B. <ol...@su...> - 2003-04-02 17:56:31
|
On Wed, Apr 02, 2003 at 09:49:46AM -0800, Jeremy Fitzhardinge wrote: > On Wed, 2003-04-02 at 08:34, Olly Betts wrote: > > > On Wed, Apr 02, 2003 at 11:23:34AM -0500, Maarten Ballintijn wrote: > > > > > { > > > > > std::string s; > > > > > s += '0'; > > > > > } > > > > > exit(0); > > > > > Just out of curiosity, why would s be destructed if you call exit()? > > > > s is destructed at the end of the block where it's defined - i.e. the > > line before exit is called. > > Do you mean the compiler is treating exit specially? No. Look at the code. s is destructed at the end of the block it is defined in. That's how C++ works. What happens after the block is irrelevant to that destruction. > Is that because > its a noreturn function? That still can't be right: if it were a > noreturn function which takes a std::string argument, then it would be > wrong to destruct the string before passing it. But it couldn't take s as an argument, as s isn't in scope at that point! Cheers, Olly |
From: Nicholas N. <nj...@ca...> - 2003-04-01 10:08:29
|
On Mon, 31 Mar 2003, Geoff Alexander wrote: > In running valgrind 1.0.4 against a small program of mine, valgrind reports "still reachable" memory at exit, both with g++ 2.95.2 and gcc 3.2 on SuSE Linux x86 7.1. I've tracked the problem down to std::string. Here's a small program that illustrates the problem: > #include <cstdlib> > #include <string> > int main(int argc, char* argv[]) > { > { > std::string s; > s += '0'; > } > exit(0); > } > Under g++ 2.95.2, valgrind reports: > ==1214== LEAK SUMMARY: > ==1214== definitely lost: 0 bytes in 0 blocks. > ==1214== possibly lost: 0 bytes in 0 blocks. > ==1214== still reachable: 1280 bytes in 1 blocks. > and under g++ 3.2, valgrind reports: > ==1236== LEAK SUMMARY: > ==1236== definitely lost: 0 bytes in 0 blocks. > ==1236== possibly lost: 0 bytes in 0 blocks. > ==1236== still reachable: 640 bytes in 1 blocks. > > Note that the amount of memory report as "still reachable" grows larger > as more characters are appended to s. I suspect that the "still > reachable" memory is a static buffer allocated in std::string, rather > than leaked memory. Is this correct? If so, is there way to tell > valgrind not to report the memory allocated this std::string static > buffer. It shouldn't be static -- the leak checker only considers dynamically allocated blocks. It sounds pretty harmless, if you want to suppress it, download v1.9.4 and use the "Leak" suppression type (1.0.4 doesn't support it). Ignore what it says about 1.9.4 being "development" -- it's more stable and generally better than 1.0.4. Note that you have to write the suppression type as "Memcheck:Leak" for 1.9.4, see the supplied .supp files for examples. Also note that when writing suppressions you have to give the _mangled_ name for C++ functions -- use the --demangle=no option to Valgrind to find them out. HTH. N |
From: Geoff A. <gal...@nc...> - 2003-04-02 05:05:21
|
----- Original Message -----=20 From: "Nicholas Nethercote" <nj...@ca...> To: "Geoff Alexander" <gal...@nc...> Cc: <val...@li...> Sent: Tuesday, April 01, 2003 5:08 AM Subject: Re: [Valgrind-users] "still reachable" memory from g++'s = std::string > On Mon, 31 Mar 2003, Geoff Alexander wrote: >=20 > > In running valgrind 1.0.4 against a small program of mine, valgrind = reports "still reachable" memory at exit, both with g++ 2.95.2 and gcc = 3.2 on SuSE Linux x86 7.1. I've tracked the problem down to = std::string. Here's a small program that illustrates the problem: > > #include <cstdlib> > > #include <string> > > int main(int argc, char* argv[]) > > { > > { > > std::string s; > > s +=3D '0'; > > } > > exit(0); > > } > > Under g++ 2.95.2, valgrind reports: > > =3D=3D1214=3D=3D LEAK SUMMARY: > > =3D=3D1214=3D=3D definitely lost: 0 bytes in 0 blocks. > > =3D=3D1214=3D=3D possibly lost: 0 bytes in 0 blocks. > > =3D=3D1214=3D=3D still reachable: 1280 bytes in 1 blocks. > > and under g++ 3.2, valgrind reports: > > =3D=3D1236=3D=3D LEAK SUMMARY: > > =3D=3D1236=3D=3D definitely lost: 0 bytes in 0 blocks. > > =3D=3D1236=3D=3D possibly lost: 0 bytes in 0 blocks. > > =3D=3D1236=3D=3D still reachable: 640 bytes in 1 blocks. > > > > Note that the amount of memory report as "still reachable" grows = larger > > as more characters are appended to s. I suspect that the "still > > reachable" memory is a static buffer allocated in std::string, = rather > > than leaked memory. Is this correct? If so, is there way to tell > > valgrind not to report the memory allocated this std::string static > > buffer. >=20 > It shouldn't be static -- the leak checker only considers dynamically > allocated blocks. >=20 > It sounds pretty harmless, if you want to suppress it, download v1.9.4 = and > use the "Leak" suppression type (1.0.4 doesn't support it). Ignore = what > it says about 1.9.4 being "development" -- it's more stable and = generally > better than 1.0.4. Note that you have to write the suppression type = as > "Memcheck:Leak" for 1.9.4, see the supplied .supp files for examples. > Also note that when writing suppressions you have to give the = _mangled_ > name for C++ functions -- use the --demangle=3Dno option to Valgrind = to find > them out. >=20 > HTH. >=20 > N >=20 >=20 >=20 > ------------------------------------------------------- > This SF.net email is sponsored by: ValueWeb:=20 > Dedicated Hosting for just $79/mo with 500 GB of bandwidth!=20 > No other company gives more support or power for your dedicated server > http://click.atdmt.com/AFF/go/sdnxxaff00300020aff/direct/01/ > _______________________________________________ > Valgrind-users mailing list > Val...@li... > https://lists.sourceforge.net/lists/listinfo/valgrind-users Thanks for the suggestions. I realize the leak checker only considers = dynamically allocated blocks. What I meant by "static buffer" is that = the address of the dynamically allocated block is being saved in a = static variable (really a misuse of the term "static buffer") and not = being freed when s is destructed. I investigated this further, and = indeed this is the case. In both g++ 2.95.2 and g++ 3.2, the allocated = memory is being saved in the static char* _S_start_free member of template <bool threads, int inst> class __default_alloc_template which is defined in stl_alloc.h (g++ 2.95.2) or bits/stl_alloc.h (g++ = 3.2). So, it seems that the "leaked" memory is allocated as part of = gcc's STL memory management. I was able to suppress the leak using = valgrind 1.9.4. For g++ 2.95.2, my suppression file is #-------- For g++ 2.95.2 { malloc/__default_alloc_template<true, 0>::_S_chunk_alloc(unsigned = int, int &) Memcheck:Leak fun:malloc fun:_S_chunk_alloc__t24__default_alloc_template2b1i0UiRi } and for g++ 3.2, my suppression file is #-------- For g++ 3.2 { __builtin_new/operator = new(unsigned)/std::__default_alloc_template<true, = 0>::_S_chunk_alloc(unsigned, int&) Memcheck:Leak fun:__builtin_new fun:_Znwj fun:_ZNSt24__default_alloc_templateILb1ELi0EE14_S_chunk_allocEjRi } Thanks again for your help. Geoff Alexander |
From: Maarten B. <maa...@mi...> - 2003-04-02 17:11:04
|
Hi, Thanks! Silly me, completely missed the extra braces :-/ Maarten. On Wed, 2003-04-02 at 11:34, Olly Betts wrote: > On Wed, Apr 02, 2003 at 11:23:34AM -0500, Maarten Ballintijn wrote: > > > > { > > > > std::string s; > > > > s += '0'; > > > > } > > > > exit(0); > > > Just out of curiosity, why would s be destructed if you call exit()? > > s is destructed at the end of the block where it's defined - i.e. the > line before exit is called. > > Cheers, > Olly > |
From: Jeremy F. <je...@go...> - 2003-04-02 17:55:01
|
On Wed, 2003-04-02 at 09:10, Maarten Ballintijn wrote: > Thanks! Silly me, completely missed the extra braces :-/ Oh, yeah. Mass silliness. J |