I think I just found an optimizer bug
So I started getting weird segfaults in minisphere after a recent change, but they'd only show up in a release build and were 100% non-reproducible in an unoptimized build. I figured I was invoking undefined behavior somewhere, but skimming my code everything looked fine.
I have the following declaration at the top of debugger.c:
static vector_t* s_sources;
This vector maintains a list of sources without a backing script file, e.g. scripts embedded in a map file. Keeping that code in memory enables SSJ to download it later for display. The vector is properly initialized on startup:
s_sources = vector_new(sizeof(struct source));
And if I print out its length right then, I get zero as expected. However I was getting segfaults later on accessing that same vector, verified by adding debugging information to the release build, and examining its contents showed it had insane garbage values. Very strange. Now mind you, by specification in C static variables are always supposed to be initialized to zero on startup if they don't have an explicit initializer. However, making the following change fixes the crash...
static vector_t* s_sources = NULL;
...and introduces a new crash when accessing a completely unrelated static vector later on! I'm pretty sure the optimizer is at fault here, because turning off optimization makes the segfaults stop, even still using the release CRT. Are the uninitialized static variables being optimized away even though they are assigned to later on? If so, why didn't this issue show up long before now since the minisphere codebase has always had a lot of static variables? I'm completely baffled. I mean, even if the pointer isn't actually initialized to zero, it still shouldn't be crashing since it's assigned a valid value before anything else is done with it.