katastic/openglad

segfault due to vbutton and globals

Opened this issue · 6 comments

vbutton is written (terribly) to use globals, AND, when triggering certain menus, it will delete all previous (global) buttons. so if you quit a round (it pops up "are you sure"), if you press yes and then immediately hit G and T, it can segfault because its attempting to both go into the training menu, and the GO (next round) menu. The call stack deletes the buttons out from UNDER the lower levels of the stack, so when it returns, it ends up calling methods on freed memory.

the solution is either to prevent this case from ever happening, or, properly, change button code (both the glad code and the new opensource c++ button code... together... ugh) to properly be stack based.

There's also a rare scenario I've seen where it'll occur WITHOUT a nested stack showing in the backtrace. But I haven't been able to reliably trigger that one yet.

Speaking of which, now I can trigger it just escaping out of a map sometimes. No nest.

#0 0x00005555555b1d84 in vbutton::leftclick(int) (this=0x555555f6fdc0, use_1_for_hotkey=1) at ../src/button.cpp:413
#1 0x00005555555b1a18 in vbutton::leftclick(button*) (this=0x5555558fd730, buttons=0x0) at ../src/button.cpp:340
#2 0x0000555555567af8 in mainmenu() () at ../src/picker.cpp:766
#3 0x00005555555665df in picker_main(int, char**) (argc=1, argv=0x7fffffffded8) at ../src/picker.cpp:185
#4 0x00005555555bb157 in main(int, char**) (argc=1, argv=0x7fffffffded8) at ../src/glad.cpp:85

I can trigger it (not always) by just hitting ESCAPE, yes [to quit], and ESCAPE again.

It may depend on the compiled code. so different minor changes to code may change the layout of memory reducing or increasing the crash likelyhood.

3 0x00007ffff7726f36 in __GI___assert_fail
(assertion=0x55555567295b "hotkey < 300", file=0x555555672949 "../src/button.cpp", line=410, function=0x555555672a20 "Sint32 vbutton::leftclick(Sint32)") at assert.c:101
4 0x00005555555b1d44 in vbutton::leftclick(int) (this=0x555555f65810, use_1_for_hotkey=1) at ../src/button.cpp:410
5 0x00005555555b1a18 in vbutton::leftclick(button*) (this=0x5555558f46a0, buttons=0x0) at ../src/button.cpp:340
6 0x0000555555567af8 in mainmenu() () at ../src/picker.cpp:766
7 0x00005555555665df in picker_main(int, char**) (argc=1, argv=0x7fffffffdf18) at ../src/picker.cpp:185
8 0x00005555555bb157 in main(int, char**) (argc=1, argv=0x7fffffffdf18) at ../src/glad.cpp:85

also I changed hotkey to be unsigned, so "hotkey < 300" doesn't fail to notice -113052325 like values

ERROR: Abort Mission, Quit this mission?:
we're calling do_call with myfunc=28
ERROR: YES
ERROR: Loading save: save0
ERROR: Loading campaign: org.openglad.gladiator
ERROR: Loading version 6 scenario
we're calling do_call with myfunc=11

YES_OR_NO = 28
RETURN_MENU = 11