|
From: Christian P. <tr...@ge...> - 2005-08-26 01:21:26
|
Hi all, my daemon running on a production server having lots of I/O a day is=20 eating the RAM really wastinly. Well, of course, it'ms my fault, somehow, but I didn't manage to get rid of all of them _yet_. Two of the memory leaks I reproduced using valgrind are as follows: =3D=3D16981=3D=3D 84 bytes in 3 blocks are still reachable in loss record 1= 1 of 28 =3D=3D16981=3D=3D at 0x1B9008C1: malloc (vg_replace_malloc.c:149) =3D=3D16981=3D=3D by 0x1D87B205: ??? =3D=3D16981=3D=3D by 0x1D87A1A9: ??? =3D=3D16981=3D=3D by 0x1D87A457: ??? =3D=3D16981=3D=3D by 0x1D87A950: ??? =3D=3D16981=3D=3D by 0x1D86F2CD: ??? =3D=3D16981=3D=3D by 0x1D86F5DA: ??? =3D=3D16981=3D=3D by 0x1D20ADFF: gethostbyname2_r (in /lib/libc-2.3.5.so) =3D=3D16981=3D=3D by 0x1D20ABCB: gethostbyname2 (in /lib/libc-2.3.5.so) =3D=3D16981=3D=3D by 0x1C39406B: System::Network::THostAddress::fromHost= Name(System::TStringBase<char> const&, System::Network::THostAddress::TFami= ly) (Utils.cp =3D=3D16981=3D=3D by 0x1CB5E371: htutils::hasIP(System::TStringBase<char= > const&) (htutils.cpp:102) =3D=3D16981=3D=3D by 0x1CB5F3AA: htutils::htmlFormat(System::TStringBase= <char> const&) (htutils.cpp:446) =3D=3D16981=3D=3D by 0x1CB92A5A: yacs::TMessageFormatter::formatChatCode= (System::TStringBase<char> const&) (TMessageFormatter.cpp:54) =3D=3D16981=3D=3D by 0x1CB94CCD: System::TFunctorHandler<System::TFuncto= r<System::TStringBase<char>, System::TTypeList<System::TStringBase<char> co= nst&, System: =3D=3D16981=3D=3D by 0x1CB93246: System::TFunctor<System::TStringBase<ch= ar>, System::TTypeList<System::TStringBase<char> const&, System::NullType> = >::operator() =3D=3D16981=3D=3D by 0x1CB92428: yacs::TBasicMessageFormatter::formatMes= sage(System::TStringBase<char> const&, System::TStringBase<char> const&) (T= MessageFormat =3D=3D16981=3D=3D by 0x1CB929F9: yacs::TMessageFormatter::format(System:= :TStringBase<char> const&, System::TStringBase<char> const&) (TMessageForma= tter.cpp:50) =3D=3D16981=3D=3D by 0x1D5B7204: ??? =3D=3D16981=3D=3D by 0x1D5BE701: ??? =3D=3D16981=3D=3D by 0x1BA7F18D: System::TFunctor<void, System::TTypeLis= t<yacs::TNetClientSession&, System::TTypeList<System::TDynamicArray<System:= :TStringBase< =3D=3D16981=3D=3D by 0x1BA6F471: yacs::TServer::handleCmd(yacs::TNetClie= ntSession*, System::TStringBase<char> const&, System::TDynamicArray<System:= :TStringBase< =3D=3D16981=3D=3D by 0x1BA56F73: yacs::TNetClientSession::handleInput() = (TNetClientSession.cpp:109) =3D=3D16981=3D=3D by 0x1BA56D24: yacs::TNetClientSession::onInput(System= ::Network::TNetworkStream*) (TNetClientSession.cpp:85) =3D=3D16981=3D=3D by 0x1BA5BAEA: System::TMemFunHandler<System::TFunctor= <void, System::TTypeList<System::Network::TNetworkStream*, System::NullType= > >, yacs::TN =3D=3D16981=3D=3D by 0x1C393206: System::TFunctor<void, System::TTypeLis= t<System::Network::TNetworkStream*, System::NullType> >::operator()(System:= :Network::TNe =3D=3D16981=3D=3D by 0x1C39276A: System::Network::TNetworkStreamPrivate:= :onDataAvailableNow(int, System::IO::Unix::TPollMask) (TNetworkStreamPrivat= e.cpp:160) =3D=3D16981=3D=3D by 0x1C393873: System::TMemFunHandler<System::TFunctor= <void, System::TTypeList<int, System::TTypeList<System::IO::Unix::TPollMask= , System::Nul =3D=3D16981=3D=3D by 0x1C35F03D: System::TFunctor<void, System::TTypeLis= t<int, System::TTypeList<System::IO::Unix::TPollMask, System::NullType> > >= ::operator()( =3D=3D16981=3D=3D by 0x1C367356: System::IO::Unix::TPollMgr::TInterest::= notify(System::IO::Unix::TPollMask) (TPollMgr.cpp:232) =3D=3D16981=3D=3D by 0x1C36708A: System::IO::Unix::TPollMgr::processPend= ing() (TPollMgr.cpp:193) =3D=3D16981=3D=3D by 0x1C366DEF: System::IO::Unix::TPollMgr::dispatchOnc= e(System::TTimeSpan) (TPollMgr.cpp:139) =3D=3D16981=3D=3D by 0x1BA6E07E: yacs::TServer::run() (TServer.cpp:383) =3D=3D16981=3D=3D by 0x8064F38: serve(System::TVarData const&) (yacsd.cp= p:326) =3D=3D16981=3D=3D by 0x80667C7: main (yacsd.cpp:412) Interestingly, the man-page doesn't tell me anything about=20 gethostbyname_r() to be free()d afterwards. So, I don't=20 understand in why it leaks there. However, this does not lead me into blindly assuming,=20 that it's glibc's fault here. But what could be wrong there? And this is another odd one: =3D=3D16981=3D=3D 4088 bytes in 1 blocks are still reachable in loss record= 22 of 28 =3D=3D16981=3D=3D at 0x1B9008C1: malloc (vg_replace_malloc.c:149) =3D=3D16981=3D=3D by 0x1CCF63BD: my_once_alloc (in /usr/lib/libmysqlclie= nt_r.so.14.0.0) =3D=3D16981=3D=3D by 0x1CCF6466: my_once_strdup (in /usr/lib/libmysqlcli= ent_r.so.14.0.0) =3D=3D16981=3D=3D by 0x1CCF7021: (within /usr/lib/libmysqlclient_r.so.14= =2E0.0) =3D=3D16981=3D=3D by 0x1CCFFF78: (within /usr/lib/libmysqlclient_r.so.14= =2E0.0) =3D=3D16981=3D=3D by 0x1CD1026D: my_xml_parse (in /usr/lib/libmysqlclien= t_r.so.14.0.0) =3D=3D16981=3D=3D by 0x1CD004DA: my_parse_charset_xml (in /usr/lib/libmy= sqlclient_r.so.14.0.0) =3D=3D16981=3D=3D by 0x1CCF6A10: (within /usr/lib/libmysqlclient_r.so.14= =2E0.0) =3D=3D16981=3D=3D by 0x1CCF6C8F: (within /usr/lib/libmysqlclient_r.so.14= =2E0.0) =3D=3D16981=3D=3D by 0x1CCF76B8: get_charset_by_csname (in /usr/lib/libm= ysqlclient_r.so.14.0.0) =3D=3D16981=3D=3D by 0x1CD1504B: mysql_real_connect (in /usr/lib/libmysq= lclient_r.so.14.0.0) =3D=3D16981=3D=3D by 0x1CB4313A: MySQL::connect(System::TStringBase<char= > const&, System::TStringBase<char> const&, System::TStringBase<char> const= &, System::TS =3D=3D16981=3D=3D by 0x1BA704DE: yacs::TServer::createConnection() const= (TServer.cpp:590) =3D=3D16981=3D=3D by 0x1BA70575: yacs::TServer::initializeTables() (TSer= ver.cpp:600) =3D=3D16981=3D=3D by 0x1BA6683E: yacs::TServer::TServer(int, System::TSt= ringBase<char> const&, System::TStringBase<char> const&, System::TStringBas= e<char> const =3D=3D16981=3D=3D by 0x806380C: spawnServer() (yacsd.cpp:281) =3D=3D16981=3D=3D by 0x80659FA: main (yacsd.cpp:388) I'm pretty sure, that mysql_close() gets invoked everywhere, but somehow,=20 libmysqlclient leaks here a memory block regarding its connection establish= ment. Well, I'm linking against the _r version of libmysqlclient, becuase it is s= upposed to be fully multi threaded (some day) and I wanted to be on the safe side, but I don't think that this is *causing* the leak. And yet, I do not understand in why this is happening here :( I'd welcome any kinda hints, thanks in advance, Christian Parpart. |
|
From: Bob R. <bo...@br...> - 2005-08-26 02:24:28
|
On Fri, Aug 26, 2005 at 03:21:09AM +0200, Christian Parpart wrote: > Hi all, > > my daemon running on a production server having lots of I/O a day is > eating the RAM really wastinly. Well, of course, it'ms my fault, somehow, > but I didn't manage to get rid of all of them _yet_. > > Two of the memory leaks I reproduced using valgrind are as follows: > > ==16981== 84 bytes in 3 blocks are still reachable in loss record 11 of 28 > ==16981== at 0x1B9008C1: malloc (vg_replace_malloc.c:149) > ==16981== by 0x1D87B205: ??? > ==16981== by 0x1D87A1A9: ??? > ==16981== by 0x1D87A457: ??? > ==16981== by 0x1D87A950: ??? > ==16981== by 0x1D86F2CD: ??? > ==16981== by 0x1D86F5DA: ??? > ==16981== by 0x1D20ADFF: gethostbyname2_r (in /lib/libc-2.3.5.so) > ==16981== by 0x1D20ABCB: gethostbyname2 (in /lib/libc-2.3.5.so) > ==16981== by 0x1C39406B: System::Network::THostAddress::fromHostName(System::TStringBase<char> const&, System::Network::THostAddress::TFamily) (Utils.cp Is the line above part of your code? If so, the comment below applies here instead. > ==16981== by 0x1CB5E371: htutils::hasIP(System::TStringBase<char> const&) (htutils.cpp:102) It's possible that the leak is here. Do you allocate memory at this line? > ==16981== by 0x1CB5F3AA: htutils::htmlFormat(System::TStringBase<char> const&) (htutils.cpp:446) > ==16981== by 0x1CB92A5A: yacs::TMessageFormatter::formatChatCode(System::TStringBase<char> const&) (TMessageFormatter.cpp:54) > ==16981== by 0x1CB94CCD: System::TFunctorHandler<System::TFunctor<System::TStringBase<char>, System::TTypeList<System::TStringBase<char> const&, System: > ==16981== by 0x1CB93246: System::TFunctor<System::TStringBase<char>, System::TTypeList<System::TStringBase<char> const&, System::NullType> >::operator() > ==16981== by 0x1CB92428: yacs::TBasicMessageFormatter::formatMessage(System::TStringBase<char> const&, System::TStringBase<char> const&) (TMessageFormat > ==16981== by 0x1CB929F9: yacs::TMessageFormatter::format(System::TStringBase<char> const&, System::TStringBase<char> const&) (TMessageFormatter.cpp:50) > ==16981== by 0x1D5B7204: ??? > ==16981== by 0x1D5BE701: ??? > ==16981== by 0x1BA7F18D: System::TFunctor<void, System::TTypeList<yacs::TNetClientSession&, System::TTypeList<System::TDynamicArray<System::TStringBase< > ==16981== by 0x1BA6F471: yacs::TServer::handleCmd(yacs::TNetClientSession*, System::TStringBase<char> const&, System::TDynamicArray<System::TStringBase< > ==16981== by 0x1BA56F73: yacs::TNetClientSession::handleInput() (TNetClientSession.cpp:109) > ==16981== by 0x1BA56D24: yacs::TNetClientSession::onInput(System::Network::TNetworkStream*) (TNetClientSession.cpp:85) > ==16981== by 0x1BA5BAEA: System::TMemFunHandler<System::TFunctor<void, System::TTypeList<System::Network::TNetworkStream*, System::NullType> >, yacs::TN > ==16981== by 0x1C393206: System::TFunctor<void, System::TTypeList<System::Network::TNetworkStream*, System::NullType> >::operator()(System::Network::TNe > ==16981== by 0x1C39276A: System::Network::TNetworkStreamPrivate::onDataAvailableNow(int, System::IO::Unix::TPollMask) (TNetworkStreamPrivate.cpp:160) > ==16981== by 0x1C393873: System::TMemFunHandler<System::TFunctor<void, System::TTypeList<int, System::TTypeList<System::IO::Unix::TPollMask, System::Nul > ==16981== by 0x1C35F03D: System::TFunctor<void, System::TTypeList<int, System::TTypeList<System::IO::Unix::TPollMask, System::NullType> > >::operator()( > ==16981== by 0x1C367356: System::IO::Unix::TPollMgr::TInterest::notify(System::IO::Unix::TPollMask) (TPollMgr.cpp:232) > ==16981== by 0x1C36708A: System::IO::Unix::TPollMgr::processPending() (TPollMgr.cpp:193) > ==16981== by 0x1C366DEF: System::IO::Unix::TPollMgr::dispatchOnce(System::TTimeSpan) (TPollMgr.cpp:139) > ==16981== by 0x1BA6E07E: yacs::TServer::run() (TServer.cpp:383) > ==16981== by 0x8064F38: serve(System::TVarData const&) (yacsd.cpp:326) > ==16981== by 0x80667C7: main (yacsd.cpp:412) > > Interestingly, the man-page doesn't tell me anything about > gethostbyname_r() to be free()d afterwards. So, I don't > understand in why it leaks there. > However, this does not lead me into blindly assuming, > that it's glibc's fault here. But what could be wrong there? If you allocated memory at the line that I pointed out, then that's the memory that was most likely leaked. It can be difficult to track down *where* it leaked, but at least you know where it was allocated for. Bob Rossi |
|
From: Igmar P. <mai...@jd...> - 2005-08-26 06:38:13
|
> Interestingly, the man-page doesn't tell me anything about > gethostbyname_r() to be free()d afterwards. So, I don't > understand in why it leaks there. Probably the char *buf argument : It's a user supplied buffer, en depending on how you allocate it, it's subject to a free() when it's malloc()'ed. I've can't remember what *ret and **result was all about, perhaps someone can shed a light on this. > However, this does not lead me into blindly assuming, > that it's glibc's fault here. But what could be wrong there? Writing a small testcase usually show how to deal with gethostbyname_r(). > And this is another odd one: > > ==16981== 4088 bytes in 1 blocks are still reachable in loss record 22 of 28 > ==16981== at 0x1B9008C1: malloc (vg_replace_malloc.c:149) > ==16981== by 0x1CCF63BD: my_once_alloc (in /usr/lib/libmysqlclient_r.so.14.0.0) > ==16981== by 0x1CCF6466: my_once_strdup (in /usr/lib/libmysqlclient_r.so.14.0.0) > ==16981== by 0x1CCF7021: (within /usr/lib/libmysqlclient_r.so.14.0.0) > ==16981== by 0x1CCFFF78: (within /usr/lib/libmysqlclient_r.so.14.0.0) > ==16981== by 0x1CD1026D: my_xml_parse (in /usr/lib/libmysqlclient_r.so.14.0.0) > ==16981== by 0x1CD004DA: my_parse_charset_xml (in /usr/lib/libmysqlclient_r.so.14.0.0) > ==16981== by 0x1CCF6A10: (within /usr/lib/libmysqlclient_r.so.14.0.0) > ==16981== by 0x1CCF6C8F: (within /usr/lib/libmysqlclient_r.so.14.0.0) > ==16981== by 0x1CCF76B8: get_charset_by_csname (in /usr/lib/libmysqlclient_r.so.14.0.0) > ==16981== by 0x1CD1504B: mysql_real_connect (in /usr/lib/libmysqlclient_r.so.14.0.0) > ==16981== by 0x1CB4313A: MySQL::connect(System::TStringBase<char> const&, System::TStringBase<char> const&, System::TStringBase<char> const&, System::TS > ==16981== by 0x1BA704DE: yacs::TServer::createConnection() const (TServer.cpp:590) > ==16981== by 0x1BA70575: yacs::TServer::initializeTables() (TServer.cpp:600) > ==16981== by 0x1BA6683E: yacs::TServer::TServer(int, System::TStringBase<char> const&, System::TStringBase<char> const&, System::TStringBase<char> const > ==16981== by 0x806380C: spawnServer() (yacsd.cpp:281) > ==16981== by 0x80659FA: main (yacsd.cpp:388) > > I'm pretty sure, that mysql_close() gets invoked everywhere, but somehow, > libmysqlclient leaks here a memory block regarding its connection establishment. > Well, I'm linking against the _r version of libmysqlclient, becuase it is supposed > to be fully multi threaded (some day) and I wanted to be on the safe side, > but I don't think that this is *causing* the leak. Looks like a mysql problem to me. Regards, Igmar |
|
From: Dennis L. <pla...@in...> - 2005-08-26 07:50:04
|
At 03:21 26.08.2005, Christian Parpart wrote: Does the number of blocks increase during run ? I remember my glibc having a little memleak in gethostbyname, and another case were some static buffer was allocated, but not freed at program end, but that was totally ok as it was only a few bytes. There was also a part in the function where an old buffer was freed() when the function was called again, so if the number of reachable blocks does not increase, theres no reason to worry about. Btw, to all others in the list, can I somehow print the address of the memory still reachable/leaked ? It would help to track it down when writing memory addresses of various internal stuff.. >==16981== 84 bytes in 3 blocks are still reachable in loss record 11 of 28 >==16981== at 0x1B9008C1: malloc (vg_replace_malloc.c:149) > >Interestingly, the man-page doesn't tell me anything about >gethostbyname_r() to be free()d afterwards. So, I don't >understand in why it leaks there. Thats right, you are not supposed to free() anything the function gives you. This looks like a MySQL bug, but again the question is, if the number of blocks increases, since this is a still reachable memory, so mysql has still a pointer to it, and this might just be some internal buffer. otherwise, you might want to try to mail the developers on their mailinglist... >And this is another odd one: > >==16981== 4088 bytes in 1 blocks are still reachable in loss record 22 of 28 >==16981== at 0x1B9008C1: malloc (vg_replace_malloc.c:149) >I'm pretty sure, that mysql_close() gets invoked everywhere, but somehow, >libmysqlclient leaks here a memory block regarding its connection >establishment. I think its not a *real* leak since the app still has a pointer to it, it could be as well some internal buffer. Usually only those are leaks where valgrind says they are definitely or possibly lost. Reachable memory is generally only then a leak when the number of allocated blocks increases during runtime. But of course, to every rule, there is an exception... greets Dennis Carpe quod tibi datum est |
|
From: Tom H. <to...@co...> - 2005-08-26 07:55:53
|
In message <6.1.2.0.0.20050826094230.02b81878@192.168.5.6>
Dennis Lubert <pla...@in...> wrote:
> Btw, to all others in the list, can I somehow print the address of the
> memory still reachable/leaked ? It would help to track it down when
> writing memory addresses of various internal stuff..
No, because valgrind doesn't remember that when it is searching for
leaks because it wants to aggregate leaks together - each leak report
may correspond to a number of blocks so there is no one block whose
address could be printed.
Tom
--
Tom Hughes (to...@co...)
http://www.compton.nu/
|
|
From: Dennis L. <pla...@in...> - 2005-08-26 09:56:36
|
Am Freitag, den 26.08.2005, 08:55 +0100 schrieb Tom Hughes: > In message <6.1.2.0.0.20050826094230.02b81878@192.168.5.6> > Dennis Lubert <pla...@in...> wrote: > > > Btw, to all others in the list, can I somehow print the address of the > > memory still reachable/leaked ? It would help to track it down when > > writing memory addresses of various internal stuff.. > > No, because valgrind doesn't remember that when it is searching for > leaks because it wants to aggregate leaks together - each leak report > may correspond to a number of blocks so there is no one block whose > address could be printed. Ok, sounds reasonable. But wasnt there a way to print every single lost block, like with something leak-check=full ? So would it perhaps be possible to implement it there ? I think it would be a nice feature to identify some hard to track-down memory leaks. Sometimes there are lots of objects created, which cause the same stack trac, but their point of destruction is sometimes here, sometimes there, and sometimes you miss one of them to destroy. So I think it could be helpful to be able to print the address of the objects as they traverse some internals, and at the end look which of those objects it was, that was leaked. I think this could help to track down the leaks... Just if its easy to implement, otherwise there is still the way to printf in destructor and look which object was not destroyed, although not so easy and straightforward than it could be ;) greets Dennis |
|
From: Christian P. <tr...@ge...> - 2005-08-26 11:17:30
|
On Friday 26 August 2005 09:50, Dennis Lubert wrote: > Btw, to all others in the list, can I somehow print the address of the > memory still reachable/leaked ? It would help to track it down when writi= ng > memory addresses of various internal stuff.. Also very helpful would be a dump of those memory blocks to be reviewed in = a=20 special output file (in what format ever). Bewides, is it possible to generate a memory dump of an application that is= =20 currently running W/O valgrind atop? Because I don't seem to reproduce the real bad leaks, but the daemon leaks= =20 within a run of about 15 hours about 500MB that doesn't get freed. I would like to be able to dump them into a file (just like the coredump, b= ut=20 w/o crashing), and review them with a hex-editor (for example). Thanks in advance, Christian Parpart. |
|
From: Jeroen N. W. <jn...@xs...> - 2005-08-26 16:55:47
|
> On Friday 26 August 2005 09:50, Dennis Lubert wrote:
> I would like to be able to dump them into a file (just like the coredump,
> but
> w/o crashing), and review them with a hex-editor (for example).
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
/* Brute force method of dumping core on the fly. */
void dump_core()
{
if (fork() == 0)
raise(SIGQUIT);
}
/* Simple program to test it. */
#include <stdio.h>
int main(int argc, char** argv)
{
printf("About to dump ...");
dump_core();
printf(" done.\n");
}
Core dumps must be enabled. (`ulimit -c unlimited` under bash.) gdb likes
the resulting core file just fine.
Jeroen.
|
|
From: Christian P. <tr...@ge...> - 2005-08-26 19:30:07
|
On Friday 26 August 2005 18:55, Jeroen N. Witmond wrote:
> > On Friday 26 August 2005 09:50, Dennis Lubert wrote:
> > I would like to be able to dump them into a file (just like the coredum=
p,
> > but
> > w/o crashing), and review them with a hex-editor (for example).
>
> #include <sys/types.h>
> #include <unistd.h>
> #include <signal.h>
>
> /* Brute force method of dumping core on the fly. */
> void dump_core()
> {
> if (fork() =3D=3D 0)
> raise(SIGQUIT);
> }
>
> /* Simple program to test it. */
> #include <stdio.h>
>
> int main(int argc, char** argv)
> {
> printf("About to dump ...");
> dump_core();
> printf(" done.\n");
> }
>
> Core dumps must be enabled. (`ulimit -c unlimited` under bash.) gdb likes
> the resulting core file just fine.
Heya, I love that piece of code :-D
However, one question may remain: why SIGQUIT and not SIGSEGV? I mean, what=
's=20
SIGQUIT been used for usually?
Thanks for the hint,
Christian Parpart.
|
|
From: Jeroen N. W. <jn...@xs...> - 2005-08-27 10:25:35
|
On Friday 26 August 2005 21:29, Christian Parpart wrote:
> On Friday 26 August 2005 18:55, Jeroen N. Witmond wrote:
>> > On Friday 26 August 2005 09:50, Dennis Lubert wrote:
>> > I would like to be able to dump them into a file (just like the
>> coredump,
>> > but
>> > w/o crashing), and review them with a hex-editor (for example).
>>
>> #include <sys/types.h>
>> #include <unistd.h>
>> #include <signal.h>
>>
>> /* Brute force method of dumping core on the fly. */
>> void dump_core()
>> {
>> if (fork() == 0)
>> raise(SIGQUIT);
>> }
>>
>> /* Simple program to test it. */
>> #include <stdio.h>
>>
>> int main(int argc, char** argv)
>> {
>> printf("About to dump ...");
>> dump_core();
>> printf(" done.\n");
>> }
>>
>> Core dumps must be enabled. (`ulimit -c unlimited` under bash.) gdb
>> likes
>> the resulting core file just fine.
>
> Heya, I love that piece of code :-D
>
> However, one question may remain: why SIGQUIT and not SIGSEGV? I mean,
> what's
> SIGQUIT been used for usually?
>
SIGQUIT (CTRL-\) is a stronger version of SIGINT (CTRL-C). The default
action is to dump core and terminate, whereas the default action of SIGINT
is just to terminate. But for the fact that it mostly originates from the
keyboard, SIGQUIT is used here for what it is intended for. Any other core
dumping signal (e.g. SIGSEGV) could be used, but that opens the door to
confusion, as they suggest errors that aren't there. (See also `man 7
signals`.)
Jeroen.
|
|
From: Christian P. <tr...@ge...> - 2005-08-27 16:06:18
|
On Saturday 27 August 2005 12:25, Jeroen N. Witmond wrote: > SIGQUIT (CTRL-\) is a stronger version of SIGINT (CTRL-C). The default > action is to dump core and terminate, whereas the default action of SIGINT > is just to terminate. But for the fact that it mostly originates from the > keyboard, SIGQUIT is used here for what it is intended for. Any other core > dumping signal (e.g. SIGSEGV) could be used, but that opens the door to > confusion, as they suggest errors that aren't there. (See also `man 7 > signals`.) Thanks! I implemented it, and it works :-D I'm now wondering on what the hell is all dumped in the core files (strings= =20 that shouldn't be there (anymore)), so, might it be, that=20 free()/delete/delete[] keeps the mmap()d regions for reuse, or did I maybe= =20 found some strings that leaked? Hm... I'll investigate on this tonight :) Thanks, Christian Parpart. |
|
From: Nicholas N. <nj...@cs...> - 2005-08-27 16:36:16
|
On Sat, 27 Aug 2005, Christian Parpart wrote: > might it be, that free()/delete/delete[] keeps the mmap()d regions for > reuse Yes. Allocators rarely give memory "back", they just hang onto it and reuse it. Look at Valgrind's allocator for an example, in coregrind/m_mallocfree.c. It allocates "superblocks" of 1MB or more using mmap(), in newSuperBlock(). It divides that up into pieces to satisfy calls to malloc(). When heap blocks are freed with free(), they are marked as reusable and put onto a "free list" (adjacent freed blocks are merged into larger blocks). This free list is what malloc() consults first when looking for a heap block. The superblocks are never deallocated as such. Nick |