如何在 linux 上正确调试交叉编译的 Windows 代码?

The*_*Vee 4 debugging wine cross-compiling mingw32

我有一小段 Windows 代码,基本上是从MSDN 教程中复制的,但适用于 C++。我现在可以使用以下方法之一编译它:

  • i686-w64-mingw32-g++ -g hello.cpp -o hello 生成本机 Windows PE32 可执行文件,

  • wineg++ -g hello.cpp -o hello产生一个libwine包装对hello.exe+ hello.exe.so

我现在想要的只是在调试器(gdb或它的接口,如果可能的话)中启动文件并在入口点处停止WinMain。我在这方面做得很差。我尝试过的(注意:在下面,hello没有扩展名的是,非常不寻常的是,Windows 可执行文件):

  • wine /usr/i686-w64-mingw32/sys-root/mingw/bin/gdbserver.exe :2000 hello其次是target remote :2000在本地gdb:根本找不到任何符号,所有内容都??在 10 多个堆栈帧中

  • wine /usr/i686-w64-mingw32/sys-root/mingw/bin/gdb.exe hello: 挂起,不接受任何用户在命令行上的输入

  • gdb wine其次是run hello: Missing separate debuginfos, use: dnf debuginfo-install wine-core-1.9.19-1.fc24.i686,我做了,错误仍然存​​在

  • gdb hello.exe.so: 导致 SIGSEGV

  • 修改hello.exe脚本,使其设置正确的环境但gdb最终运行:没有任何符号,??无处不在

  • winedbg hello有和没有--gdb到目前为止最远,从一个黑色的控制台窗口开始,让我介入,但我的代码中的任何内容仍然被??删除,并且WinMain(或任何包含该字符串的内容)是未知的

  • winedbg hello.exe(对于 )的输出wineg++:程序完全加载,调试器挂起等待它已经在后台运行

  • 运行应用程序并将其附加到winedbg: 不符合目的(不允许我停在入口点),但其他方面的工作主要类似于最后两点(与 的输出一起工作,MinGW但不显示任何内部结构hello.exe,对wineg++)的输出根本不起作用。

  • 阅读大量官方和非官方教程、错误报告、SO 问题...

我什至不记得我尝试过的其他组合。肯定不会那么难吧?

VZ.*_*VZ. 11

调试在 Wine 下运行的程序的最简单方法是在其下运行全功能的 gdbserver。首先,需要安装所需的软件包,例如在 Debian 下:

    # apt install gdb-mingw-w64 gdb-mingw-w64-target
Run Code Online (Sandbox Code Playgroud)

然后运行程序

    $ wine Z:/usr/share/win64/gdbserver.exe localhost:12345 myprogram.exe
Run Code Online (Sandbox Code Playgroud)

最后,从另一个终端/屏幕窗口:

    $ 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
Run Code Online (Sandbox Code Playgroud)

然后像往常一样正常调试,即可以完全访问调试信息和工作断点等。

特别是,跑步的gdbserver效果比使用要好得多,winedbg --gdb而使用多年来似乎已经很糟糕了。

  • 这个答案应该是 2022 年的正确答案。你的说明非常清楚,并且它们在 Debian 稳定版上对我有用。 (3认同)

The*_*Vee 8

看来我想通了。使用编译命令行

i686-w64-mingw32-g++ -gstabs hello.cpp -o hello.exe
Run Code Online (Sandbox Code Playgroud)

我可以跑

winedbg hello.exe
Run Code Online (Sandbox Code Playgroud)

并在其命令行中,

break WinMain@16
cont
Run Code Online (Sandbox Code Playgroud)

重要的选项是-gstabs代替-g和没有--gdbfor winedbg。我在阅读此邮件列表线程后发现两者都在那里讨论了更相关的信息。

请注意,裸机winedbg在名称修改等方面受到严重损害,但gdb由于上面链接中概述的原因,将无法正常工作(至少不是开箱即用)。