I am trying to get a call stack in a Windows executable. I tried several different ways to get the call stack. The following are some examples. Please note that I changed them a bit and removed the error handling so that they are easy to understand, so they cannot compile as they are. I think you understand.
A simple way:
const int max_entries = 10; void *entries[max_entries]; return CaptureStackBackTrace(0, max_entries, entries, 0);
Low level method:
const int max_entries = 10; void *entries[max_entries]; void **frame = 0; __asm { mov frame, ebp } unsigned int i = 0; while(frame && i < max_entries) { entries[i++] = frame[1]; frame = (void **)frame[0]; }
Compatible way:
void *entries[max_entries]; CONTEXT context; RtlCaptureContext(&context); STACKFRAME64 stack_frame; ZeroMemory(&stack_frame, sizeof(STACKFRAME64)); stack_frame.AddrPC.Offset = context.Eip; stack_frame.AddrPC.Mode = AddrModeFlat; stack_frame.AddrFrame.Offset = context.Ebp; stack_frame.AddrFrame.Mode = AddrModeFlat; stack_frame.AddrStack.Offset = context.Esp; stack_frame.AddrStack.Mode = AddrModeFlat; unsigned int num_frames = 0; while (true) { if (!StackWalk64(IMAGE_FILE_MACHINE_I386, GetCurrentProcess(), GetCurrentThread(), &stack_frame, &context, NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL)) break; if (stack_frame.AddrPC.Offset == 0) break; entries[num_frames++] = reinterpret_cast<void *>(stack_frame.AddrPC.Offset); }
My problem is that they work in an unoptimized build, but not with full optimization. What happens is that I get one broken record and then go out of my loops. In debugging, I get a full call stack, and when I look at the characters later, everything is correct.
I don’t understand how difficult it is to make this work in all assemblies when the debugger does this all the time. I can say that frame pointers will not be omitted in code generation. First, I create for debugging, and then change the optimization from only one to full optimization and rebuild to reproduce the call stack failure.
Any clues to the solution are welcome.
/ Jonas
callstack winapi
Jonas hultén
source share