D/DMD:退出程序会导致错误(段错误、sigabort、...)
D/DMD: Exiting program causes errors (segfault, sigabort, ...)
我有空闲时间的游戏项目,用 D、SDL2 和 OpenGL(废弃)编写,共享部分形成某种引擎。要点:
- Linux 薄荷 17.2
- DMD 2.069.0-b2(也使用了其他最新版本,例如 2.067.1)
- SDL2 2.0.2(来自存储库)
- 没有线程(只有纤维)
可以在此处访问整个源代码:https://github.com/mkoskim/games
症状: 退出 - 使用 exit() 退出并从 main() 返回 - 几乎总是导致 glibc 抛出各种信号或段错误,例如:
*** Error ...: munmap_chunk(): invalid pointer: ... *** ... Aborted
*** Error ...: double free or corruption (out): ... *** ... Aborted
*** Error ...: free(): invalid pointer: ... *** ... Aborted
*** Error ...: corrupted double-linked list: ... *** ... Aborted
*** core.exception.InvalidMemoryOperationError@src/core/exception.d(679): ...
**** Segmentation fault
做一些小的改变——比如向帧缓冲区添加析构函数class或任何东西——可以改变行为,即使那样,这也不会发生在我所有的游戏草图中。目前它发生在 'projects/cylinderium',但不会发生在像 'demo/objectview' 或 'testbench/wolfish'.
这样的项目中
我一直怀疑它是由SDL2库对象(如SDL_Surface)引起的,因为它们是在D 运行时间之外分配的,但我还没有设法找到这个。我的另一个怀疑是,从对象析构函数到例如废弃的,已经被破坏了。
基本上在关机时出现错误并不危险,因为无论如何退出都会清除所有内容。但在知道原因之前,我担心这是更严重错误的征兆,当我玩更复杂的游戏时(例如,在加载新游戏关卡时,或者 运行 长时间玩游戏时,错误会爆发时间)。
问题:
1) DMD 运行time 以什么顺序调用析构函数?它会导致例如在调用所有使用 OpenGL 函数(例如 glDeleteTextures)创建的对象的析构函数之前销毁废弃的 OpenGL 接口?
2) 我已经在自己的 classes 中挂钩了大多数析构函数,但是我可以挂钩每个析构函数以追踪 DMD 在 运行 关闭时删除的内容和删除顺序吗?
3) 如果您碰巧能够成功获取、编译和 运行 项目,我很高兴听到您是否可以重现错误。
我现在有点没有想法,任何想法都将不胜感激。
我想我找到原因了
为了完整起见,在静态构造函数中初始化 SDL (SDL_Init、TTF_Init、...) 的模块已使用静态析构函数将其关闭 (SDL_Quit ,...)。另一方面,我在分配它们的析构函数中单独删除了SDL分配的资源。这些是在运行时释放资源所必需的。
我之前已经与释放 SDL_Font* 和 SDL_Surface* 的析构函数作斗争,因此我添加了全局 SDL_up 标志以防止在 SDL 关闭后调用。
我忘记的是我还有 Joystick 管理 SDL 资源...更多调试显示模块析构函数确实在 joystick 析构函数之前调用,调用 SDL 释放资源导致错误。
修复:我从模块析构函数和 SDL_up 标志中删除了 SDL/TTF/IMG Quit 调用。这已经是我第二次因为同样的原因花费几个小时了,我决定最好不要让资源重新分配更复杂,而是放弃正统的完整 Init-Quit 调用对(并让系统退出以摆脱SDL).
我有空闲时间的游戏项目,用 D、SDL2 和 OpenGL(废弃)编写,共享部分形成某种引擎。要点:
- Linux 薄荷 17.2
- DMD 2.069.0-b2(也使用了其他最新版本,例如 2.067.1)
- SDL2 2.0.2(来自存储库)
- 没有线程(只有纤维)
可以在此处访问整个源代码:https://github.com/mkoskim/games
症状: 退出 - 使用 exit() 退出并从 main() 返回 - 几乎总是导致 glibc 抛出各种信号或段错误,例如:
*** Error ...: munmap_chunk(): invalid pointer: ... *** ... Aborted
*** Error ...: double free or corruption (out): ... *** ... Aborted
*** Error ...: free(): invalid pointer: ... *** ... Aborted
*** Error ...: corrupted double-linked list: ... *** ... Aborted
*** core.exception.InvalidMemoryOperationError@src/core/exception.d(679): ...
**** Segmentation fault
做一些小的改变——比如向帧缓冲区添加析构函数class或任何东西——可以改变行为,即使那样,这也不会发生在我所有的游戏草图中。目前它发生在 'projects/cylinderium',但不会发生在像 'demo/objectview' 或 'testbench/wolfish'.
这样的项目中我一直怀疑它是由SDL2库对象(如SDL_Surface)引起的,因为它们是在D 运行时间之外分配的,但我还没有设法找到这个。我的另一个怀疑是,从对象析构函数到例如废弃的,已经被破坏了。
基本上在关机时出现错误并不危险,因为无论如何退出都会清除所有内容。但在知道原因之前,我担心这是更严重错误的征兆,当我玩更复杂的游戏时(例如,在加载新游戏关卡时,或者 运行 长时间玩游戏时,错误会爆发时间)。
问题:
1) DMD 运行time 以什么顺序调用析构函数?它会导致例如在调用所有使用 OpenGL 函数(例如 glDeleteTextures)创建的对象的析构函数之前销毁废弃的 OpenGL 接口?
2) 我已经在自己的 classes 中挂钩了大多数析构函数,但是我可以挂钩每个析构函数以追踪 DMD 在 运行 关闭时删除的内容和删除顺序吗?
3) 如果您碰巧能够成功获取、编译和 运行 项目,我很高兴听到您是否可以重现错误。
我现在有点没有想法,任何想法都将不胜感激。
我想我找到原因了
为了完整起见,在静态构造函数中初始化 SDL (SDL_Init、TTF_Init、...) 的模块已使用静态析构函数将其关闭 (SDL_Quit ,...)。另一方面,我在分配它们的析构函数中单独删除了SDL分配的资源。这些是在运行时释放资源所必需的。
我之前已经与释放 SDL_Font* 和 SDL_Surface* 的析构函数作斗争,因此我添加了全局 SDL_up 标志以防止在 SDL 关闭后调用。
我忘记的是我还有 Joystick 管理 SDL 资源...更多调试显示模块析构函数确实在 joystick 析构函数之前调用,调用 SDL 释放资源导致错误。
修复:我从模块析构函数和 SDL_up 标志中删除了 SDL/TTF/IMG Quit 调用。这已经是我第二次因为同样的原因花费几个小时了,我决定最好不要让资源重新分配更复杂,而是放弃正统的完整 Init-Quit 调用对(并让系统退出以摆脱SDL).