Windows MinGW64 输出stackTrace信息

本文介绍了如何使用MSDN提供的CaptureStackBackTraceSymFromAddr函数,结合DbgHelp库在MinGW环境下编译和实现打印调用堆栈的功能。在测试中,成功展示了从Qt应用的事件处理到布局调整的一系列函数调用轨迹。
摘要由CSDN通过智能技术生成

分析

相关资料

MSDN: CaptureStackBackTrace SymFromAddr

待补充 傻B MinGW

编译

-lDbgHelp -g || add_compile_options(-g) add_ target_link_libraries(... DbgHelp)

实现

util.h

#ifndef UTIL_H
#define UTIL_H

class Util {
     Util() = delete;
	~Util() = delete;
public:
	static void printStackTrace();
	
};

#endif // UTIL_H

util.cpp

#include <Windows.h>
#include <dbghelp.h>

#include <array>

void Util::printStackTrace() {
    HANDLE process = GetCurrentProcess();
    HANDLE thread = GetCurrentThread();
    
    CONTEXT context;
    memset(&context, 0, sizeof(context));
    context.ContextFlags = CONTEXT_FULL;
    
    RtlCaptureContext(&context);
    SymInitialize(process, NULL, true);
    
    DWORD image = IMAGE_FILE_MACHINE_AMD64;
    
    STACKFRAME64 stackframe;
    {
    	ZeroMemory(&stackframe, sizeof(STACKFRAME64));
    	
    	// 请根据系统的arch自行填写
    	stackframe.AddrPC.Offset    = context.Rip;
    	stackframe.AddrPC.Mode      = AddrModeFlat;
    	stackframe.AddrFrame.Offset = context.Rsp;
    	stackframe.AddrFrame.Mode   = AddrModeFlat;
    	stackframe.AddrStack.Offset = context.Rsp;
    	stackframe.AddrStack.Mode   = AddrModeFlat;
	}
    
    for (size_t i = 0; i < 25; i++) {
        bool result = StackWalk64(
            image, process, thread,
            &stackframe, &context,
            nullptr,
            SymFunctionTableAccess64, SymGetModuleBase64,
            nullptr
        );
        
        if (!result) {
            break;
        }
        
        std::array<char, sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)> buffer;
        PSYMBOL_INFO symbol = reinterpret_cast<PSYMBOL_INFO>(buffer.data());
        symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
        symbol->MaxNameLen = MAX_SYM_NAME;
        
        DWORD64 displacement = 0;
        if (SymFromAddr(process, stackframe.AddrPC.Offset, &displacement, symbol)) {
            printf("[%i] 0x%x %s\n", i, symbol->Address, symbol->Name);
        } else {
            printf("[%i] 0x%x ???\n", i, symbol->Address, symbol->Name);
        }
    }
    
    SymCleanup(process);
}

某测试结果

[0] 0x1a8208f0 ???
[1] 0x1a8208f0 ???
[2] 0x16483bd0 ZN7QWidget5eventEP6QEvent
[3] 0x16447890 ZN19QApplicationPrivate13notify_helperEP7QObjectP6QEvent
[4] 0x1644e190 ZN12QApplication6notifyEP7QObjectP6QEvent
[5] 0x68a52fc0 ZN16QCoreApplication9sendEventEP7QObjectP6QEvent
[6] 0x1647a520 ZN14QWidgetPrivate15setGeometry_sysEiiiib
[7] 0x1647b660 ZN7QWidget11setGeometryERK5QRect
[8] 0x16465eb0 ZN11QWidgetItem11setGeometryERK5QRect
[9] 0x1645c5a0 ZN10QBoxLayout11setGeometryERK5QRect
[10] 0x164621d0 ZN14QLayoutPrivate8doResizeEv
[11] 0x16447890 ZN19QApplicationPrivate13notify_helperEP7QObjectP6QEvent
[12] 0x1644e190 ZN12QApplication6notifyEP7QObjectP6QEvent
[13] 0x68a52fc0 ZN16QCoreApplication9sendEventEP7QObjectP6QEvent
[14] 0x1647a520 ZN14QWidgetPrivate15setGeometry_sysEiiiib
[15] 0x1647b660 ZN7QWidget11setGeometryERK5QRect
[16] 0x16465eb0 ZN11QWidgetItem11setGeometryERK5QRect
[17] 0x1645c5a0 ZN10QBoxLayout11setGeometryERK5QRect
[18] 0x164621d0 ZN14QLayoutPrivate8doResizeEv
[19] 0x16463300 ZN7QLayout8activateEv
[20] 0x16447890 ZN19QApplicationPrivate13notify_helperEP7QObjectP6QEvent
[21] 0x1644e190 ZN12QApplication6notifyEP7QObjectP6QEvent
[22] 0x68a52920 ZN16QCoreApplication15notifyInternal2EP7QObjectP6QEvent
[23] 0x68a599a0 ZN23QCoreApplicationPrivate16sendPostedEventsEP7QObjectiP11QThreadData
[24] 0x1a8208f0 qt_plugin_instance
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值