3

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

Motti
  • 110,860
  • 49
  • 189
  • 262
  • "OutputDebugString" sounds like a Windows API function. I suggest adding a "windows" or similar tag. – foraidt Feb 04 '09 at 12:30

12 Answers12

8

If you're using visual studio you can attach the debugger and rather than having a break-point have a trace-point. You do this by right clicking the break-point and choosing When Hit.... Then select to print a message including the stack trace. This message will be sent to the output pane and you can analyze all calls at your leisure.

hit-point

Motti
  • 110,860
  • 49
  • 189
  • 262
6

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
  • 21,529
  • 9
  • 63
  • 82
3

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).

Community
  • 1
  • 1
mfazekas
  • 5,589
  • 1
  • 34
  • 25
2

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
  • 4,503
  • 1
  • 27
  • 40
  • 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* :) – Reunanen Feb 04 '09 at 11:58
1

Using gcc? Why not generate a stack trace?

Community
  • 1
  • 1
Alastair
  • 4,475
  • 1
  • 26
  • 23
1

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

Andrew Wilkinson
  • 10,682
  • 3
  • 35
  • 38
1

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
  • 21,389
  • 8
  • 58
  • 85
0

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
  • 16,230
  • 17
  • 74
  • 137
0

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.

dajood
  • 3,758
  • 9
  • 46
  • 68
0

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

See this answers
Heap corruption under Win32; how to locate?

Good lock.

Community
  • 1
  • 1
lsalamon
  • 7,998
  • 6
  • 50
  • 63
0

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
  • 3,043
  • 1
  • 21
  • 28
0

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 Feb 04 '09 at 15:48