开发者

How to debug a strange memory leak (C++)

开发者 https://www.devze.com 2022-12-21 13:44 出处:网络
I\'m writing a linux demon, and for now it works pretty well, but it leaks memory (and it\'s bad - after a few hours it segfaults after using 60% of the system\'s memory). The strange thing is that I\

I'm writing a linux demon, and for now it works pretty well, but it leaks memory (and it's bad - after a few hours it segfaults after using 60% of the system's memory). The strange thing is that I'm using only the new/delete operators and have 开发者_开发知识库a try/catch block around the main function, so it's not an exception thrown by new - it just segfaults at some point due to the lack of memory I guess.

I used valgrind, but it only found a one-time small leak and nothing else. I tried gdb too, but altough the app is compiled with the -g -rdynamic flags it does not translate all the addresses into function names.

Can you tell me some better ways of memory debugging that I could use to determine the source of the leak?


Valgrind is usually very reliable at finding leaks, so are you sure it's a memory leak?

A heap profiler can help you to see what objects you are creating and whether they are the ones you expect. Massif is one such tool that might prove useful.


A "memory leak" in C++ parlance refers to orphaned memory that hasn't been freed, but which is no longer reachable. If valgrind says that you have no leaks, then you probably are keeping pointers to objects that you no longer need. This isn't a leak, strictly speaking, but it will cause your memory usage to balloon, eventually.

If you want to use valgrind, pass the --show-reachable flag, which will have it dump all of the objects that are still reachable in memory at the time your app exits. Then you can look through those stack traces and determine which objects are being kept too long in memory and why.


As others have pointed, it probably isn't a simple leak. More likely is a wrong forced cast, which makes it misinterpret some object's type. Or a buffer under/overflow, or an integer rollover (some 32-bit signed offset getting over 2Gig?), or a dangling pointer....

In my experience, when you build complex structures, with pointers all around, you need a formal specification of the structure. Particularly important is a set of invariances. With these in hand, build both a test suite, and a run-time verifier that can assure you that your data is still consistent and tidy.


I suggest that you first try to solve your problem with gdb since it is the #1 tool to find out what happens when a segfault occurs. Then run your program until it crash, and make sure that the system generates a core file (use ulimit -c unlimited to allow the creation of a core file, be careful if it's a daemon, it must be done for the user that actually run the daemon). At this point you can use gdb with the core file to find out where the segfault happens (see. backtrack command).


It might also be a stack overflow (which would be strange of course, but it's also a possibility which fits all your problems). For example, if a function calls itself (implicitly or explicitly) after some time, this may happen. I say again that this would be a strange and very rare problem, but that's the thing that came to my mind after I read all answers and the problem.


One thing Valgrind can be poor at, is finding leaks in a threaded application. If your leak is the result of a race condition, it'll vanish during debugging, since Valgrind serializes everything.

Nearly every "leak" I've debugged, especially in even Java, has been the result of unrestricted growth in a standard collection. i.e. Vectors that never get cleaned up, dictionaries that grow beyond expectation, etc. If Valgrind isn't finding anything, there's a good chance that it's not an actual leak.


are you getting any strange warnings from your compiler or linker?? anything related to libstdc++? we had a problem where we were simultaneously linking against two separate versions of libstdc++ (5 and 6) and that gave us horrible memory leaks.


I read once that sometimes new will return NULL if you run out of memory, rather than throwing an exception. Perhaps that's causing the segfault?

0

精彩评论

暂无评论...
验证码 换一张
取 消