Как да получите проследяване на стека за извикване на процеса на отстраняване на грешки от библиотека 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

ако предпочитате c++ вместо c, можете да използвате рамката 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