Get stracktrace on application built with G++ on Windows

Viewed 28

I'm developping an application on Windows using G++/MinGW. When my application crash, I would like to log the stacktrace. I understand that I cannot use "SymGetSymFromAddr" function to retrieve the method name because it works only on executable built with Visual Studio (PDB format). Therefore, my idea is to print only the debug symbol addresses and then use "addr2line" tool to retrieve the method name / line number.

Here is the code to print the stacktrace method name addresses:

LONG WINAPI signalHandler(EXCEPTION_POINTERS* exceptionInfo) {
    HANDLE process = GetCurrentProcess();
    HANDLE thread = GetCurrentThread();
    CONTEXT* context = exceptionInfo->ContextRecord;

    SymInitialize(process, nullptr, true);
    STACKFRAME frame = {};
    frame.AddrPC.Offset = context->Rip;
    frame.AddrPC.Mode = AddrModeFlat;
    frame.AddrStack.Offset = context->Rsp;
    frame.AddrStack.Mode = AddrModeFlat;
    frame.AddrFrame.Offset = context->Rbp;
    frame.AddrFrame.Mode = AddrModeFlat;

    std::stringstream ss;
    while (StackWalk(IMAGE_FILE_MACHINE_AMD64, process, thread, &frame, context, nullptr, SymFunctionTableAccess, SymGetModuleBase, nullptr)) {
        std::string moduleName = "[unknown]";
        DWORD64 moduleBase = SymGetModuleBase(process, frame.AddrPC.Offset);
        char moduleBuffer[MAX_PATH];
        if (moduleBase && GetModuleFileNameA((HINSTANCE)moduleBase, moduleBuffer, MAX_PATH)) {
            moduleName = moduleBuffer;
        }

        void* instructionShift = (char*)frame.AddrPC.Offset;
        ss << "\t[bt]\t> " << "addr2line -f -e " << moduleName << " " << instructionShift << std::endl;
    }
    SymCleanup(process);

    Logger::instance().logError(ss.str());
    return EXCEPTION_EXECUTE_HANDLER;
}

Here is an example of result when I've got an application crash:

[bt]    > addr2line -f -e C:\msys64\home\greg\project\myApp.exe 0x7ff611d13faf
[bt]    > addr2line -f -e C:\msys64\home\greg\project\myApp.exe 0x7ff611d13763
[bt]    > addr2line -f -e C:\msys64\home\greg\project\myApp.exe 0x7ff611daf325
[bt]    > addr2line -f -e C:\WINDOWS\System32\USER32.dll 0x7ffde66f1c4c
[bt]    > addr2line -f -e C:\WINDOWS\System32\USER32.dll 0x7ffde66f189e
[bt]    > addr2line -f -e C:\WINDOWS\SYSTEM32\opengl32.dll 0x7ffd864e3554
[bt]    > addr2line -f -e C:\WINDOWS\System32\USER32.dll 0x7ffde66f1c4c
[bt]    > addr2line -f -e C:\WINDOWS\System32\USER32.dll 0x7ffde66f0ea6
[bt]    > addr2line -f -e C:\msys64\home\greg\project\myApp.exe 0x7ff611db218f
[bt]    > addr2line -f -e C:\msys64\home\greg\project\myApp.exe 0x7ff611d13a8f
[bt]    > addr2line -f -e C:\msys64\home\greg\project\myApp.exe 0x7ff611d114c6
[bt]    > addr2line -f -e C:\WINDOWS\System32\KERNEL32.DLL 0x7ffde57b54e0
[bt]    > addr2line -f -e C:\WINDOWS\SYSTEM32\ntdll.dll 0x7ffde788485b

Unfortunately, when I execute the "addr2line" command, I always get the following result:

??
??:0

I well compiled my application with debug option (-g). Therefore, why the method name is not returned by "addr2line" tool ? Or maybe it is not possible to get correct addresses with "StackWalk" function on application built with G++ ?

0 Answers
Related