Stacktrace / Stackwalk for the current process and current thread with IDebug interfaces

0

I want to use the IDebugXXX interfaces to get stack traces for some functions in my local process (no remote attaching).

Using this code the attach to the current process works, but the stack trace of the current thread alway contains only one frame like: ntdll!ZwGetContextThread+0x00000012

{
    IDebugClient* debugClient;
    IDebugControl4 *control4;

    ...

    int flags = DEBUG_ATTACH_NONINVASIVE | DEBUG_ATTACH_NONINVASIVE_NO_SUSPEND;
    debugClient->AttachProcess(0, myProcessId, flags);

    control4->SetExecutionStatus(DEBUG_STATUS_GO);


    ...

    // get the stack trace for the current thread
    control4->GetStackTrace(0, 0, 0, _stackFrames, ARRAYSIZE((_stackFrames)), &_uFramesFilled)

    // _uFramesFilled is always '1' for the current thread
}

Edit: The application is written in C++/CLI and the results for the other threads at least contain more frames.

windows
debugging
c++-cli
stack-trace
asked on Stack Overflow Jul 17, 2014 by marsh-wiggle • edited Aug 18, 2014 by Deduplicator

2 Answers

1

This works well for me: ( caution: please check the return codes of these APIs )

I think what you are missing is: "WaitForEvent" call after "AttachProcess".

IDebugClient4 * debugClient;
IDebugControl4 * control4;
DEBUG_STACK_FRAME frames[10];
ULONG filled = 0;
ULONG pid = 7288;

DebugCreate( __uuidof(IDebugClient4), (void **)&debugClient );

debugClient->QueryInterface( __uuidof(IDebugControl4), (void**)&control4 );

debugClient->AttachProcess(0, pid, DEBUG_ATTACH_NONINVASIVE | DEBUG_ATTACH_NONINVASIVE_NO_SUSPEND);

control4->WaitForEvent(DEBUG_WAIT_DEFAULT, INFINITE);

control4->GetStackTrace(0, 0, 0, &frames[0], 10, &filled);
answered on Stack Overflow Jul 17, 2014 by Icarus3
1

After reading the assert sample in WinDDK I found out that there is the context missing the stack trace has to start from. After that (and adding WaitForEvent(...)) the trace works fine.

{
    ...

    // capture the context end convert it to debug '.crx' command
    char CxrCommand[64];
    CONTEXT myContext;
    ZeroMemory(&myContext, sizeof(CONTEXT));
    RtlCaptureContext(&myContext);
    sprintf_s(CxrCommand, 64, ".cxr 0x%p", &myContext);
    // capture the context end

    ...

    control4->WaitForEvent(DEBUG_WAIT_DEFAULT, INFINITE);

    //execute debugger command: ".cxr (Display Context Record)"
    control4->Execute(DEBUG_OUTCTL_IGNORE, CxrCommand, DEBUG_EXECUTE_NOT_LOGGED

    control4->GetStackTrace( .... )
}
answered on Stack Overflow Jul 21, 2014 by marsh-wiggle • edited Jul 23, 2014 by marsh-wiggle

User contributions licensed under CC BY-SA 3.0