How to properly debug a cross-compiled Windows code on linux?
Asked Answered
E

3

16

I have a small piece of Windows code, basically one copied from the MSDN tutorial but adapted for C++. I can compile it now using one of the methods:

  • i686-w64-mingw32-g++ -g hello.cpp -o hello to produce a native Windows PE32 executable,

  • wineg++ -g hello.cpp -o hello to produce a libwine wrapper pair hello.exe + hello.exe.so.

All I want now is to start the file in a debugger (gdb or an interface to it if possible) and stop at the entry point WinMain. I'm failing badly at this. What I have tried (NB: in the following, hello without extension is, quite unconventially, the Windows executable):

  • wine /usr/i686-w64-mingw32/sys-root/mingw/bin/gdbserver.exe :2000 hello followed by target remote :2000 in a local gdb: finds no symbols at all, everything is ?? across 10+ stack frames

  • wine /usr/i686-w64-mingw32/sys-root/mingw/bin/gdb.exe hello: hangs, does not accept any user input on the command line

  • gdb wine followed by run hello: Missing separate debuginfos, use: dnf debuginfo-install wine-core-1.9.19-1.fc24.i686, which I did and the error remains

  • gdb hello.exe.so: causes a SIGSEGV

  • modifying the hello.exe script so that it sets the right environment but runs gdb in the end: no symbols whatsoever, ?? everywhere

  • winedbg hello with and without --gdb: gets the farthest so far, starts with a black console window and lets me step in, but whatever is in my code is still ??-ed out and WinMain (or anything containing that string) is not known

  • winedbg hello.exe (for the output of wineg++): the program loads fully, the debugger hangs waiting for it while it already runs in the background

  • running the application and attaching to it in winedbg: does not fit the purpose (won't allow me to stop at the entry point) but otherwise works mostly like the last two points (works with the output of MinGW but does not show any internals of hello.exe, does not work at all with the output of wineg++).

  • reading tons of official and unofficial tutorials, bug reports, SO questions...

I can't even remember the other combinations I tried. Surely it can't be that hard?

Express answered 8/10, 2016 at 23:0 Comment(0)
E
10

It seems I figured it out. With the compile command line

i686-w64-mingw32-g++ -gstabs hello.cpp -o hello.exe

I can run

winedbg hello.exe

and in its command line,

break WinMain@16
cont

The important option was -gstabs instead of -g and no --gdb for winedbg. I figured out both after reading this mailing list thread, more relevant pieces of information are discussed there.

Note that the bare winedbg is seriously impaired when it comes to name mangling and such, but gdb won't work (at least not out of the box) for the reasons outlined in the link above.

Express answered 9/10, 2016 at 11:0 Comment(0)
B
12

The simplest way to debug programs running under Wine is to run full-featured gdbserver under it. First, the required packages need to be installed, e.g. under Debian:

    # apt install gdb-mingw-w64 gdb-mingw-w64-target

Then run the program as

    $ wine Z:/usr/share/win64/gdbserver.exe localhost:12345 myprogram.exe

and, finally, from another terminal/screen window:

    $ x86_64-w64-mingw32-gdb myprogram.exe
    (gdb) set solib-search-path ...directories with the DLLs used by the program...
    (gdb) target extended-remote localhost:12345

and then debug normally as usual, i.e. with full access to debug information and working breakpoints and so on.

In particular, running gdbserver works much better than using winedbg --gdb which seems to be quite broken since many years.

Blithering answered 6/7, 2021 at 9:38 Comment(2)
This answer should be the correct answer for 2022. Your instructions are perfectly clear, and they work for me on Debian stable.Datestamp
@Blithering did you compile using wineg++ or i686-w64-mingw32-g++? in my case gdb connects to gdb server but is unable to load any info about source file... any suggestions on #72517677Bundelkhand
E
10

It seems I figured it out. With the compile command line

i686-w64-mingw32-g++ -gstabs hello.cpp -o hello.exe

I can run

winedbg hello.exe

and in its command line,

break WinMain@16
cont

The important option was -gstabs instead of -g and no --gdb for winedbg. I figured out both after reading this mailing list thread, more relevant pieces of information are discussed there.

Note that the bare winedbg is seriously impaired when it comes to name mangling and such, but gdb won't work (at least not out of the box) for the reasons outlined in the link above.

Express answered 9/10, 2016 at 11:0 Comment(0)
D
4

You can run winedbg --gdb --no-start progra.exe. And after this you can use Hopper disassembler and attach to the port you get.

Dactylology answered 10/10, 2016 at 2:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.