【问题标题】:How to get a callstack trace of debug process by WinDbg library如何通过 WinDbg 库获取调试过程的调用堆栈跟踪
【发布时间】:2019-09-28 11:14:39
【问题描述】:

我需要通过windbg库获取调试过程的调用堆栈跟踪。 因此,也欢迎对理论有所帮助的答案。 感谢您的帮助!

注意0: 我认为这个问题在这种形式下可能更容易理解: 如何将堆栈解析为帧以获取函数调用和参数?

注意: 例如,我可以在进程的某个地方,通过断点,获取 ESP 寄存器的值,但是如何解析呢?还是有其他办法?

注2: 有类似的问题:How do I determine detailed call-stack information in C++?

【问题讨论】:

  • 如果我理解正确,您想在 C++ 中使用 windbg 引擎来获取调用堆栈吗?如果“windbg 库”是指dbgeng,那么您需要set a breakpoint,然后是examine the stack 跟踪。
  • 64 位还是 32 位?这些差别很大。开始使用~kr 看看是不是你想要的。

标签: c++ windbg


【解决方案1】:

如果您的意思是使用 dbgeng,请参阅下面的原型。当我从一个更大的项目 (NetExt) 中获取它时,您可能需要进行调整才能对其进行编译。

#include <dbgeng.h>
    IDebugClient *Client;
    PDEBUG_CONTROL5 Control;
    PDEBUG_SYMBOLS5 symbol;
    HRESULT Hr;


    Hr = S_OK;

    if ((Hr = DebugCreate(__uuidof(IDebugClient),
                          (void **)&Client)) != S_OK)
    {
        return Hr;
    }

    if ((Hr = Client->QueryInterface(__uuidof(IDebugControl5),
                                  (void **)&Control)) == S_OK)
    {



                DEBUG_STACK_FRAME_EX listFrames[100] = {0};

                UINT total = 0;

                Client->QueryInterface(__uuidof(IDebugSymbols5),
                                (void **)&symbol)
                if (Control->GetStackTraceEx(0, 0, 0, &listFrames, 100, &total) == S_OK)
                {

                    for (UINT i=0; i < total; i++)
                    {
                        printf("%i\n", i);
                        printf("\tfInstructionOffset = %p\n", listFrames[i].InstructionOffset);

                        printf("\tfReturnOffset = %p\n", listFrames[i].ReturnOffset);

                        printf("\tFrameOffset = %p\n", listFrames[i].FrameOffset);

                        printf("\tInlineFrameContext = %p\n", listFrames[i].InlineFrameContext);

                        std::string strSymbol('\0', 100);
                        UINT size, displ = 0;

                        if (symbol->GetNameByOffset(listFrames[i].InstructionOffset, const_cast<char*>(strSymbol.c_str()), 100, &size, &displ) == S_OK)
                        {

                            strSymbol.resize(size);

                        }

                        printf("\tFunction = %s\n", strSymbol.c_str());


                    }                   
                }
        }

【讨论】:

    【解决方案2】:

    如果你更喜欢 c++ 而不是 c,你可以使用 windbg sdk 提供的 engextcpp 框架

    提供可单击 dml 链接的示例代码,单击该链接时将在当前指令指针处打印调用堆栈

    编译前的目录内容

    D:\barebones>ls
    barebones.cpp  barebones.def
    

    源代码

    D:\barebones>cat barebones.cpp
    
    #include <engextcpp.cpp>
    #pragma comment (lib ,"dbgeng.lib")
    class EXT_CLASS : public ExtExtension
    {
    public:
        EXT_COMMAND_METHOD(barebones);
    };
    EXT_DECLARE_GLOBALS();
    EXT_COMMAND(barebones,"","")
    {
            DmlCmdExec( "CallStack\n","kb");
    }
    

    def文件的内容

    D:\barebones>cat barebones.def
    EXPORTS
    
    DebugExtensionInitialize
    DebugExtensionUninitialize
    DebugExtensionNotify
    barebones
    

    init vs devcmd 提示

    D:\barebones>runvs
    
    D:\barebones>pushd .
    
    D:\barebones>cd /d "c:\Program Files\Microsoft Visual Studio\2017\Community\Common7\Tools\"
    
    c:\Program Files\Microsoft Visual Studio\2017\Community\Common7\Tools>vsdevcmd.bat
    **********************************************************************
    ** Visual Studio 2017 Developer Command Prompt v15.9.4
    ** Copyright (c) 2017 Microsoft Corporation
    **********************************************************************
    
    c:\Program Files\Microsoft Visual Studio\2017\Community\Common7\Tools>popd
    

    目录后编译链接的内容

    D:\barebones>cl /Zi /W3 /EHsc /Od /LD /nologo /I e:\windjs\windbg_18362\inc barebones.cpp /link /release /def:barebones.def /nologo
    barebones.cpp
       Creating library barebones.lib and object barebones.exp
    
    D:\barebones>ls -lg
    total 7684
    -rw-rw-rw-  1 0     247 2019-10-03 16:46 barebones.cpp
    -rw-rw-rw-  1 0      96 2019-10-03 16:09 barebones.def
    -rw-rw-rw-  1 0  373248 2019-10-03 16:54 barebones.dll
    -rw-rw-rw-  1 0    1198 2019-10-03 16:54 barebones.exp
    -rw-rw-rw-  1 0    2520 2019-10-03 16:54 barebones.lib
    -rw-rw-rw-  1 0  460094 2019-10-03 16:54 barebones.obj
    -rw-rw-rw-  1 0 6500352 2019-10-03 16:54 barebones.pdb
    -rw-rw-rw-  1 0  512000 2019-10-03 16:54 vc140.pdb
    
    D:\barebones>
    

    用法

    .load {path to barebones.dll}
    type !barbones and hit enter 
    click the link Named CallStack to get a stacktrace
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-28
      • 2011-04-23
      • 1970-01-01
      • 2020-03-03
      • 1970-01-01
      • 2014-08-13
      • 1970-01-01
      相关资源
      最近更新 更多