Как получить трассировку стека вызовов процесса отладки с помощью библиотеки WinDbg

Мне нужно получить трассировку стека вызовов процесса отладки с помощью библиотеки windbg. Таким образом, ответы, которые могут помочь с теорией, также приветствуются. Спасибо за помощь!

Примечание 0: я думаю, что вопрос может быть более понятен в такой форме: как разобрать стек на кадры, чтобы получить вызовы функций и аргументы?

Примечание. Например, я могу в каком-то месте процесса по точке останова получить значение регистра ESP, но как его разобрать? Или есть другой способ?

Примечание 2. Аналогичный вопрос был там: Как мне определить подробную информацию о стеке вызовов в C++?


person SovietVenator    schedule 28.09.2019    source источник
comment
Если я правильно понимаю, вы хотели бы использовать движок Windbg на C++ для получения стека вызовов? Если под библиотекой Windbg вы имеете в виду dbgeng затем вам нужно set a breakpoint, а затем examine the stack.   -  person Neitsa    schedule 30.09.2019
comment
64 бит или 32 бит? Эти очень сильно отличаются. Начните использовать ~, k и r, чтобы понять, хотите ли вы этого.   -  person Thomas Weller    schedule 30.09.2019


Ответы (2)


Если вы имеете в виду использование 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());


                    }                   
                }
        }
person Rodney Viana    schedule 03.10.2019

если вы предпочитаете С++ вместо С, вы можете использовать инфраструктуру engextcpp, поставляемую с WindBG SDK

пример кода, который предоставляет интерактивную ссылку 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 против 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

введите здесь описание изображения

person blabb    schedule 03.10.2019