SDL2和GDB:编程接收信号?,未知信号

cru*_*ear 6 c++ gcc gdb sdl-2

让我们从描述发生了什么开始:

我在Windows上玩SDL2库.我可以使用它编译程序,当我运行.exe时它工作得很好.当我尝试使用GDB调试它时出现问题 - 当代码进入SDL_Init或SDL_OpenAudio函数(可能创建新线程),GDB停止,显示"程序接收信号?,未知信号"消息,并且当我恢复执行时程序崩溃.

显然,GDB(https://www.mail-archive.com/cygwin@cygwin.com/msg149735.html)中存在与线程命名相关的错误,应该在GDB版本7.11.1-1中修复.

起初我使用GCC 5.1.0(TDM)和GDB 7.6.1,所以我决定更新到更新的版本.看起来大约两年前TDM没有提供任何更新,所以我安装了MinGW-w64(我现在不记得了,但它可能是GDB的7.11版本).没有帮助,GDB stil崩溃了.

接下来我搜索了更新版本的GDB,找到了7.12(www dot equation dot com/servlet/equation.cmd?fa = gdb).也没有工作,也许修复没有达到这个版本.

显然这个bug应该只存在于x86版本的GDB中,所以我安装了x64版本的TDM(GCC 5.1.0和GDB 7.9.1).程序编译正常,但GDB仍然捕获未知信号和程序崩溃.

现在我实际上无法使用SDL2调试任何程序.所以,问题是,我能做些什么让它再次运作?


可能的解决方案:

  • 使用Visual Studio - 我喜欢Eclipse(这意味着我开始容忍我不喜欢的东西)并且不想学习全新的IDE,但我会将其作为最后一个选项.
  • 编译GDB - 尝试过,没有用,在Windows上编译的东西几乎从不适合我,而且GDB 7.12也有这个bug.
  • 切换到Linux - 比转移到Visual Studio更加激进的选择.
  • 回归到SDL 1.2 - 事情变得更容易了......
  • 切换到任何其他库 - ...并希望他们将与GDB合作.这听起来并不像解决方案.
  • 切换到不同的编译器?
  • 禁用线程命名?

代码示例:

#include <SDL2/SDL.h>

// Normally I'd use #undef main
int WinMain(int, char**)
    {
    SDL_Init(SDL_INIT_EVERYTHING);

    return 0;
    }
Run Code Online (Sandbox Code Playgroud)

编译:g ++ gdbtest.cpp -lSDL2main -lSDL2

SDL2版本:2.0.5(适用于Windows的最新版本,MinGW,32位版本)


正常运行:a.exe

结果:程序正常启动和结束

使用GDB运行:控制台日志

结果:GDB收到未知信号,程序崩溃

cru*_*ear 5

好的,我想我找到了两种处理方法。问题的根源在于 GDB 如何处理(或至少应该处理)线程命名。要命名线程,必须引发具有特定属性的异常。SDL2 在位于 SDL2-2.0.5/src/thread/windows/SDL_systhread.c:168 的 SDL_SYS_SetupThread 函数中执行此操作:

RaiseException(0x406D1388, 0, sizeof(inf) / sizeof(ULONG), (const ULONG_PTR*) &inf);
Run Code Online (Sandbox Code Playgroud)

第一个选项是注释这一行并重新编译库(好吧,编译它本身就是一个问题)。第二种选择是添加:

SDL_SetHint(SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING, "1");
Run Code Online (Sandbox Code Playgroud)

在代码早期的某个地方 - 在 SDL_SYS_SetupThread 函数中,有一个对 SDL_GetHintBoolean 的调用,如果 SDL_HINT_WINDOWS_... 为假,则该函数从函数返回而不命名任何内容。

尽管如此,找到解决这个错误的方法并不意味着它不会回来困扰我,因为其他一些库命名了它的线程。