我有自由时间的游戏项目,用D,SDL2和OpenGL(废弃)编写,共享部分形成引擎排序。要点:
可以在此处访问整个来源: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
进行小的更改 - 比如向Framebuffer类或任何东西添加析构函数 - 可以改变行为,即使这样,这也不会发生在我拥有的每个游戏草图中。目前它发生在'projects / cylinderium'中,但不会发生在像'demo / objectview'或'testbench / wolfish'这样的项目中。
我很久以来一直怀疑它是由SDL2库对象(如SDL_Surface)引起的,因为它们是在D运行时之外分配的,但我还没有设法跟踪它。我的另一个嫌疑人是从对象析构函数调用到例如废弃,已经被毁坏了。
基本上在关机时获取错误并不危险,因为退出无论如何都会清除所有内容。但在知道原因之前我担心这是一个更严重的错误的症状,当我有更复杂的游戏时(例如在加载新的游戏级别或长时间运行游戏时)会爆炸。
问题:
1)DMD运行时调用析构函数的顺序是什么?它会导致例如在使用OpenGL函数(例如glDeleteTextures)的所有创建对象的析构函数被调用之前被废除的废弃OpenGL接口?
2)我已经在我自己的类中挂钩了大多数析构函数,但是我可以挂钩每个析构函数来跟踪DMD在运行时关闭时删除的内容和顺序吗?
3)如果您碰巧能够成功获取,编译和运行项目,我很高兴听到您是否可以重现该错误。
此刻我有点想法,任何想看的地方都会受到赞赏。
答案 0 :(得分:0)
我想我找到了原因。
为了完整起见,在静态构造函数中初始化了SDL(SDL_Init,TTF_Init,...)的模块具有静态析构函数来关闭它们(SDL_Quit,...)。另一方面,我已经分别删除了SDL在已经分配它们的析构函数中分配的资源。这些是在运行时释放资源所必需的。
我之前已经在解析SDL_Font *和SDL_Surface *的析构函数,因此我添加了全局SDL_up标志以防止SDL关闭后的调用。
我忘记的是我还有Joystick管理SDL资源...更多调试显示模块析构函数确实在操纵杆析构函数之前被调用,并且调用SDL释放资源导致错误。
FIX:我从模块析构函数和SDL_up标志中删除了SDL / TTF / IMG Quit调用。这已经是我第二次因为同样的原因花费了数小时和数小时,我决定最好不要使资源释放更复杂,而是放弃orthodoxis完整的Init-Quit调用对(并让系统退出以摆脱SDL)。