cpp获取当前堆栈信息

在这里插入图片描述

#include "stdafx.h"
#include <windows.h>
#include <dbghelp.h>
#pragma comment(lib, "dbghelp.lib")![在这里插入图片描述](https://img-blog.csdnimg.cn/20191010113640475.png)
#define INVALID_FP_RET_ADDR_VALUE 0x00000000
BOOL g_fSymInit;
HANDLE g_hProcess;

//address of the founction stack-call to walk.

BOOL DisplaySymbolDetails(DWORD dwAddress)
{
    DWORD64 displacement = 0;
    ULONG64 buffer[(sizeof(SYMBOL_INFO) +
        MAX_SYM_NAME*sizeof(TCHAR) +
        sizeof(ULONG64) - 1) /
        sizeof(ULONG64)];

    PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;

    pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);

    pSymbol->MaxNameLen = MAX_SYM_NAME;

    if (SymFromAddr(g_hProcess, dwAddress, &displacement, pSymbol))

    {

        // Try to get the Module details

        IMAGEHLP_MODULE64 moduleinfo;

        moduleinfo.SizeOfStruct = sizeof(IMAGEHLP_MODULE64);

        if (SymGetModuleInfo64(g_hProcess, pSymbol->Address, &moduleinfo))

        {

            printf("%s!", moduleinfo.ModuleName);

        }

        else

        {

            printf("<ErrorModuleInfo_%d>!", GetLastError());

        }



        // now print the function name

        if (pSymbol->MaxNameLen > 0)

        {

            printf("%s", pSymbol->Name);

        }

        else

        {

            printf("<Unknown_Function>");

        }

    }

    else

    {

        printf(" <Unable to get symbol details_%d>", GetLastError());

    }



    return TRUE;

}

//采用内联汇编获取当前stack Frame地址和当前程序指令地址.

bool WalkTheStack()
{
    DWORD _ebp = INVALID_FP_RET_ADDR_VALUE;
    DWORD dwIPOfCurrentFunction = (DWORD)&WalkTheStack;

    // Get the current Frame pointer
    __asm

    {
        mov[_ebp], ebp
    }

    // We cannot walk the stack (yet!) without a frame pointer
    if (_ebp == INVALID_FP_RET_ADDR_VALUE)
        return false;
    printf("CurFP\t\t\tRetAddr\n");

    //current Frame Pointer

    DWORD *pCurFP = (DWORD *)_ebp;

    BOOL fFirstFP = TRUE;

    while (pCurFP != INVALID_FP_RET_ADDR_VALUE)

    {

        // pointer arithmetic works in terms of type pointed to. Thus,

        // "+1" below is equivalent of 4 bytes since we are doing DWORD

        // math.

        // Find Caller,next print.

        DWORD pRetAddrInCaller = (*((DWORD *)(pCurFP + 1)));

        printf("%p\t\t%p  ", pCurFP, (DWORD *)pRetAddrInCaller);



        if (g_fSymInit)

        {

            if (fFirstFP)

            {

                fFirstFP = FALSE;

            }



            DisplaySymbolDetails(dwIPOfCurrentFunction);



            // To get the name of the next function up the stack,

            // we use the return address of the current frame

            dwIPOfCurrentFunction = pRetAddrInCaller;

        }



        printf("\n");

        if (pRetAddrInCaller == INVALID_FP_RET_ADDR_VALUE)

        {

            // StackWalk is over now...

            break;

        }



        // move up the stack to our caller

        DWORD pCallerFP = *((DWORD *)pCurFP);

        pCurFP = (DWORD *)pCallerFP;

    }



    return true;

}

int _tmain(int argc, _TCHAR* argv[])
{
    // Initialize the debugger services to retrieve detailed stack info

    g_fSymInit = FALSE;
    g_hProcess = GetCurrentProcess();
    if (!SymInitialize(g_hProcess, NULL, TRUE))
    {
        printf("Unable to initialize symbols!\n\n");
    }

    g_fSymInit = TRUE;

    //SYMOPT_UNDNAME:All symbols are presented in undecorated form.

    //SYMOPT_INCLUDE_32BIT_MODULES:

    //When debugging on 64-bit Windows, include any 32-bit modules.

    //SYMOPT_ALLOW_ABSOLUTE_SYMBOLS:

    //Enables the use of symbols that are stored with absolute addresses. instead of RAVS forms.

    SymSetOptions(SYMOPT_UNDNAME | SYMOPT_INCLUDE_32BIT_MODULES | SYMOPT_ALLOW_ABSOLUTE_SYMBOLS);

    if (WalkTheStack() == false)

        printf("Stackwalk failed!\n");



    return 0;

}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值