views:

505

answers:

12

Looking for a quick and dirty way to identify the caller of a constructor (or any function for that matter) I am writing macros to help identify memory leaks by dumping the "this" pointers to OutputDebugString.

Knowing where ctor and dtor was called from would help identify the problem.

tnx \0

+6  A: 

The best way I can think of is to run your program in a debugger and put a breakpoint in the constructor. Next, examine the call stack.

If you want to target one specific allocation in one specific class, you can keep an allocation count and see which allocation number doesn't get freed. Run the program again, and break on the right allocation number.


If you need to have the call stack dumped to a log, I know it is possible to generate a stack dump using for example win32 API. A more general approach would be to keep an explicit call stack as a global/thread specific state, for example in an std::vector<std::string>-object. (Use RAII to ensure that every push_back is accompanied by a pop_back)

Magnus Hoff
Doesn't work if that constructor gets called lots of times and only one of the calling functions forgets to tidy up...
graham.reeds
graham.reeds: True. I added a small paragraph on using an allocation counter.
Magnus Hoff
+2  A: 

There is no quick and dirty way for this, C++ does not offer any portable way of looking into a stack-trace. If you want to search for memory-leaks, I'd recommend looking into valgrind and similar tools, they do a great job. As coding guideline, avoid memory-leaks in the first place by using RAII (always have an owner for a resource).

gimpf
No offense, but I don't see how you came to the conclusion that a quick and dirty way (to do something like this, which most probably would stay in the code only temporarily) would really need to be *portable* :)
Pukku
:D jepp, you're right on your blind spot here...
gimpf
A: 

You running under Windows? Visual Leak Detector has helped me in the past find memory leaks.

Using RAII helps reduce memory leaks too.

If you are feeling adventurous then you can overload the new and delete functions. Paul Nettle does this in his MMGR.

graham.reeds
A: 

Can you manipulate the ctor and dtor? I'm no C++ developer and you should easily see this, but perhaps in this case you could pass i.e. a reference on the caller to the constructor.

BloodySmartie
+1  A: 

Using gcc? Why not generate a stack trace?

Alastair
+1  A: 

If you're using Linux then Valgrind does everything you want and more. I find it indispensable when developing in C++.

Andrew Wilkinson
A: 

Basically you don't, instead of you save all allocation/deallocation and discover who don´t free objects/areas.

See this answers
http://stackoverflow.com/questions/1069/heap-corruption-under-win32-how-to-locate/380781#380781

Good lock.

lsalamon
A: 

The advise to use a debugger and the call stack is sound and probably the best solution possible. However if you are without a debugger it will not be much help.

Do you know the calling convention being used for your constructor? If so you can use some inline assembler (provided your compiler supports it) to examine the order of function calls. With std calling, the most common convention for Win32, popping the stack will reveal the pointer to the address to return to after the function has been called (i.e. some place in the calling function). This isn't ideal, but you can then go backwards from that point until you reach an address you know to be the start of a function. The only problem here is that you need to get the addresses for all of your functions to be able to do this... this can be done using a simple trick to get the value of eip into another register right at the top of the function, then moving this value into an array to be checked against later when debugging, something like (intel syntax):

call label
label:
pop eax
mov [address of next array entry], eax
jheriko
A: 

If you're using g++, you can build your project for coverage. When you run over some sample code, you can then view the coverage of your program using gcov.

This output includes the call tree, and you should be able to see calls to constructors, and the functions that are calling them.

The only downside I can think of is that you will only get output for code that is actually executed, and so you'll need to have good test cases. That being said, performing coverage analysis is well worth it anyway. Finally, I highly recommend that you use lcov to view the results!

Richard Corden
+7  A: 
Motti
+3  A: 

It seems to be you are on windows (OutputDebugString). So you can use the StackWalk64 api to get the stacktrace. See the "Printing the stack trace in C++ (MSVC)" question for more details.

There is also a lot of leak detection tool available (BoundsChecker, etc).

mfazekas
A: 

Thanks everyone for the feedback. putting a break point in the ctor is not an option due to hundreds of calls for new objects in even a short lifecycle of the program.

Tracing macros in the ctor and dtor did the trick.

Visual Leak Detector and Stackwalk64 look very promising

also found AfxDumpStack(AFX_STACK_DUMP_TARGET_ODS); // OutputDebugString
but it is VERY noisy

Welcome to Stack Overflow! :) It is customary to add these kinds of thanks and summaries to your question. The answers are sorted by votes, so your comments here may seem a bit out of place. It is also customary to mark an answer as accepted, if you feel that a given answer is "correct". Have fun :)
Magnus Hoff