分析
相关资料
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