Search code examples
memory-leakswindbgbreakpointsvisual-studio-debuggingcallstack

Record call stack and values on breakpoint?


Background

I'm trying to track down a memory leak issue, where I know (from _CRT_DEBUG_MALLOC and MFC's and the CRT's leak detection) the specific line of where memory is leaked, but since this line is invoked so often, I do not know which call actually leaks. And the Allocation-Number + __p__crtBreakAlloc() doesn't help, because it's a different allocation number each run.

Anyways, so far for background. If you think I should be using a different tool, please leave a comment. I would appreciate if answers concentrate on the actual question instead of my underlying problem, as I find that much more interesting than the leak itself (I'll find that eventually through enough poking).

Question

Is it possible in WinDbg (I'm pretty sure it ain't in VS) to have a breakpoint with the following properties:

  • It doesn't break. (So it's a "tracepoint")
  • When hit, it records the call stack (up to a certain depth)
  • It should also record some global state (variables, maybe just the raw value of a memory address)

Is this possible? How?


Solution

  • To answer each of your question points:

    • breakpoint without breaking:

      bp myDll!<namespace>::myClass::myFunc "gc" - you can execute commands delimited by double quotes, in this case when the breakpoint is hit, just continue

    • on hitting breakpoint dump the call stack up a certain depth

      .kframes 0n50; bp myDll!<namespace>::myClass::myFunc "kb;gc" - this sets the call stack length to 50 (the default is 20), the 0n tells it we are decimal based. the command in double quotes after bp will dump the call stack and then continue

    • record some global state

      dt myVar - will display global variables, additionally so will using d* myVar

      dd myGlobalVar

      make sure pdbs do not have private symbols stripped - you should check the info for dt as there are specific switches to handle unicode strings, depths etc.., additionally you can easily observe the values in the watch window in WinDbg, plus see the doc about d*

    Additionally there is an automated leak detection command in WinDbg:

    !heap -l
    

    but I have found it a bit hit and miss sometimes, more info here