Walking the stack - one more way

Recently I’ve been trying to move MemTracer from experiment category to something that’s actually usable in real world scenario. It requires more work than I expected, but it’s slowly moving forward. One of the first problems I encountered was StackWalk64 function. It works nicely, but when called very often it can cause noticeable slowdowns. Walking the stack can be done manually by ESP/EBP traversing, but on Windows XP/Vista platforms it’s actually easier to use undocumented RtlCaptureStackBackTrace function. Example:

USHORT (WINAPI *s_pfnCaptureStackBackTrace)(ULONG, ULONG,
if (s_pfnCaptureStackBackTrace == 0)
    const HMODULE hNtDll = ::GetModuleHandle("ntdll.dll");
        reinterpret_cast<void*&>(s_pfnCaptureStackBackTrace) =
        ::GetProcAddress(hNtDll, "RtlCaptureStackBackTrace");
numEntries = s_pfnCaptureStackBackTrace(entriesToSkipAtStart,
    maxDepth, reinterpret_cast<PVOID*>(&callStack[0]), 0);

It’s perfect for tools like MemTracer, because it’s very lightweight, doesnt care about symbols, it’ll only grab return addresses and more detailed info can be extracted later.

Old comments

Kurak 2008-01-21 19:56:14

And rest are PR guys, right? ;)

Riddlemaster 2008-01-23 21:16:46

I dunno whether it is temporary issue and whether it concerns other people as well, but on Opera on 1680x1050 resolution side menu overlaps with the content.

Hello 2012-05-31 19:09:31

psh, real programmers use inline assembly. :)
No seriously, you can get the EBP register saved into local var which will form the head of a linked list of pointers that point to the next EBP location for lower stack frames. Just beneath the stored EBP register is the return address, save these in an array and you can resolve them later (symbol lookup is going to be really slow). This is probably the fastest way to do it on x86 as you don’t need to call into a Win32 API.

admin 2012-05-31 19:51:23

Yeah, that’s what I meant by EBP/ESP traversing (–> also http://msinilo.pl/blog/?p=764 :)