This is happening for me on Windows in compile mode. Steps to reproduce:
- Create a new game with one object (no room!)
- Compile an exe of it (opening the exe will crash)
- Add to the create event a call to
- Compile an exe again, opening it this time will not crash <
current_captionglobal initialization. I figured it out by removing
-sfrom the SHELL Makefile for compile mode, then adding
-g3 -ggdbto get the symbols. I did a full clean rebuild and got the below stack trace. Note the length 12 is because I changed the two vars to initialize to
#18569 0x0000000000535593 in var::var<char >(char const (&) ) [clone .constprop.0] () #18570 0x0000000000535593 in var::var<char >(char const (&) ) [clone .constprop.0] () #18571 0x0000000000535593 in var::var<char >(char const (&) ) [clone .constprop.0] () #18572 0x000000000053603d in global constructors keyed to 65535_0_SHELLmain.o.70040 () #18573 0x0000000000485b32 in __do_global_ctors () at E:/mingwbuild/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/gccmain.c:67 #18574 0x0000000000485b8f in __main () at E:/mingwbuild/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/gccmain.c:83 #18575 0x000000000040137f in __tmainCRTStartup () at E:/mingwbuild/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/crtexe.c:329 #18576 0x00000000004014db in WinMainCRTStartup () at E:/mingwbuild/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/crtexe.c:195
It's not clear to me why calling
string_heightfixes anything. It's also not clear to me that we're seeing recursion. Sounds like an undefined access that adding another method call is masking. I suggest
room_captionis being initialized to
room.caption, which is OOB. Maybe declaring that create event pushes another string in the way. Either way, the problem is likely with how
room_captionis initialized. Not with recursion between two constructors.
Here's the thing, I deleted my earlier comment. If you change
draw_textthat also works, as well as just about any other function in
draw_get_fontwhich do not fix it. Rusky suggested it might just be functions that take var, but I tried
stringwhich do not fix it. Pretty weird, but I think it's just related to the fact that this only occurs with
-fltowhich must be separating the code segments into Enclaves.
Now let me explain why I think it's recursion other than the stack being 20,000 frames of var construction. If I add an overload to
variant_string_wrapper that takes
const char* then the recursion goes away but I end up with a memmove segfault, which I think is caused by the release just below that.
That's a weird problem to encounter. And that solution shouldn't work. It seems GCC is up to its old antics of trying to hop from type A to type B via var. That isn't legal and I don't understand how it's doing that. Can you get line numbers?
Right, no I don't think I can get line numbers because it only occurs with
-fltowhich destroys that. I mean, it's giving line numbers, they just happen to be in linker-separated modules instead of the original line numbers. If you have an idea of what to add to the
-g3 -ggdbI used to get the original line numbers, please share.
Ok, so I decided to do some printing from the constructors to get us some more information and see all the variables involved here as well as exactly which constructors are running. I discovered that as far as strings go, it is just the caption basically. However, I also realized that we are casting the room caption every step to
std::stringand checking if it's empty to set the window caption.
I had to comment that out for a second in order to see first the constructors that are being run.
********* EXECUTE: C:/msys64/tmp/egm13900845851131715855.exe rvalue_ref string variant_string_wrapper() this be the room caption variant(const char *str) this be the room caption rvalue_ref string variant_string_wrapper() this be the current caption variant(const char *str) this be the current caption Initializing audio system...
I then gave this a go in compile mode and the stack trace was totally different. I even uncommented the setting of the room caption again and got the same.
Thread 1 received signal SIGSEGV, Segmentation fault. 0x00000000005339d0 in enigma::propagate_locals(enigma::object_planar*) [clone .cold] () (gdb) bt #0 0x00000000005339d0 in enigma::propagate_locals(enigma::object_planar*) [clone .cold] () #1 0x0000000000992850 in ?? () Backtrace stopped: previous frame inner to this frame (corrupt stack?) (gdb)
Once I set the two caption vars back to empty string literals, I was able to get back to the original issue.
#0 0x0000000000532c62 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) [clone .isra.0] [clone .lto_priv.6] () #1 0x0000000000532cc4 in var::var<char >(char const (&) ) [clone .constprop.0] ()
So it just seems it's something to do with the linker optimization not liking vars constructed from empty string literals.