Using dbg-library with mingw w64 and x86-64 architecture

Issue #11 new
Andre Netzeband
created an issue

Hi

With the current code, I had no success to get the library running for x86-64 architecture compiled with mingw-w64. However I adapted the library a little bit and was able to get it running. A patch file is attached to this ticket.

What did I changed? First of all I had to compile the library with the option

force.cppflags = ['-mtune=generic', '-march=x86-64'] 

in my doozer configuration.

But then the assembler fails due to some x86 (32 bit) specific inline assembler directives. The solution is quite easy. With mingw-w64 and x86-64 architecture, we can simply use RtlCaptureContext to capture the context.

So I added another compile condition to the "MINGW32" test in windows/frames.cpp, that checks if we are not using 64 bit architecture. If we use 64 bit architecture the else-path with RtlCaptureContext is compiled instead.

However after this change the program counter addresses I got were invalid and I was not able to get any symbols out of it. By reading the error code (that is not printed out by default :/ ) I found out, that a SymInitialize seems to be missing before calling StackWalk64.

I added a call to this function directly before starting the stack-walk and this function is also called for 32 bit targets. I guess this is also necessary for 32 bit systems, however I did not check afterwards if it still runs on 32 bit.

The other changes in the patch-file are just some log-output adaptations. They are not necessary for 64 bit systems ;-) (the only relevant change is in "src/windows/frames.cpp")

I hope my patch-file helps you to fix the issue with mingw-w64 and x86-64 systems.

Thanks a lot for this library! I used it some time ago in a 32 bit project and I missed it a lot in my current 64 bit project. Now I can use it again. Yeah! ;-)

Best regards, André Netzeband

Comments (2)

  1. renaud lepere

    I had a similar need, but I did another fix for a similar problem... I saw your post only latter, I don't know if this can be useful or not.

        #elif defined(__MINGW32__) && defined(_M_AMD64)
        DWORD64 rip_val = 0;
        DWORD64 rsp_val = 0;
        DWORD64 rbp_val = 0;
    
        __asm__ __volatile__ ("call 1f\n\t" "1: pop %0" : "=g"(rip_val));
        __asm__ __volatile__ ("movq %%rsp, %0" : "=g"(rsp_val));
        __asm__ __volatile__ ("movq %%rbp, %0" : "=g"(rbp_val));
    
        context.Rip = rip_val;
        context.Rsp = rsp_val;
        context.Rbp = rbp_val;
        skip = 2;
    

    Thanks for the great library, very useful to fix bugs without launching a debugger.

  2. Log in to comment