我需要通过windbg库获取调试过程的调用堆栈跟踪。 因此,也欢迎有理论帮助的答案。 感谢您的帮助!
注意0: 我认为以这种形式可以更容易理解这个问题: 如何将堆栈解析为框架以获取函数调用和参数?
注意: 例如,我可以在某个过程中通过断点获取ESP寄存器值,但是如何解析呢?还是有其他方法?
注2: 那里存在类似的问题:How do I determine detailed call-stack information in C++?
答案 0 :(得分:0)
如果您要使用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());
}
}
}
答案 1 :(得分:0)
如果您更喜欢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