I’ve got a (mostly) working CHIP-8 emulator that uses SDL for rendering. It’s a single-threaded application written in c++, and I’ve been referencing quite a few different example programs to make sure that everything is more or less correct, but I’ve been running into some strangely random segmentation faults.
Mostly, it seems to be crashing while running SDL_PollEvent()- The stack-trace showing a few function calls beyond that terminating at getenv().
Outside of a single use-case, it seems perfectly stable. If I click the close button, the window closes, and the program terminates gracefully. If I press almost any key, and do the same, the window closes, and the program terminates gracefully. If I proc an SDL_EXIT event, while pressing a key that the emulated program accepts in that frame- Such as while moving a paddle in PONG- Then the program segfaults.
I have tried tracking down why, and have not had much luck. My input handling isn’t entirely standard- The only event I actually check for is the SDL_EXIT event- I run SDL_PollEvent() in a while loop every frame until it’s emptied, and use SDL’s internal keyboard state to check if any given key is pressed.
I’ve reproduced this issue under Ubuntu 22.04 (SDL2-2.0.20) and NixOS Unstable (SDL2-2.28.3)
I’ve got a fairly complicated setup here- Mostly by design. I wanted to structure everything in a way that would mimic the actual layout of a chip-8 computer. I have half-baked plans of using the interpreter as the foundation for a VHDL implementation of the CPU.
Anyways, the breakdown is like this- I have classes for the RAM, ROM loading, input handling, the interpreter itself, and the display- All of these are tied together via a BUS class, and ultimately, everything is instanced in a class that controls it all.
SDL is initialized in the top-level chip-8 class I’ve dubbed “tehCHIP”. Ignoring my naming scheme, this has a screen class object, dubbed “tehSCREEN”- And I pass a pointer to that object onto the BUS, which is the only thing that can perform operations on it. (And I’m just now realizing that I ought to simply be instancing all of these class objects in the bus, because that would cut down on pointer weirdness. I’m going to go ahead and see if that helps any.)
Input and other such things are also handled in the BUS class.
The program, as it is, is single-threaded- I’ve got plans to change this, but I know very well SDL does not like being on its own thread on some platforms.
If there’s anything there that catches your eye as a potential problem… Yeah, that tracks. Feel free to poke me for actual code, or any other info in particular.
What happens if you comment out the line this->exit = true;? If that still leads to a crash in this specific situation then I would suspect a bug in SDL because a program should be able to keep going as normal even after receiving a SDL_QUIT event as far as I understand.
Are you calling process_events() from multiple places? Are you sure you don’t do any cleanup as a result of exit being set to true before you are done handling the keys, calling process_events(), etc.?
It’s usually very difficult to help when people only post a small amount of code like this because the problem is very often in some other part that the person does not suspect. The problem might be caused by some memory corruption in a totally unrelated part of the program.
What I often find very useful is to run the program through valgrind or compile the program with sanitizers (e.g. -fsanitize=undefined,address if you’re using GCC). That’ll often show you an error closer to the real problem, which is not always close to where the crash happened (assuming you even got a crash).
The program crashes, in this case.
I’m also only calling process_events() once every frame- I double-checked to ensure I’m not erroneously calling it from anywhere else.
Recompiling with fsanitize=undefined,address turned out to be rather helpful. I had a stack overflow in my pixel-drawing code, I was doing some math to find an index for an array of pixels that’d get fed into SDL_UpdateTexture()- I didn’t do any error checking on the input to the function that calculated this array, which is unfortunate as the Chip-8 display is supposed to handle wraparound in the first place. It was a very simple fix, and I’ve found that now, the program does not seem to crash at all. I believe it was writing pixel data out of bounds, and silently breaking something important in the background.
I’d already tried using valgrind to suss out an issue with it, but I wasn’t having any luck. Thank you so much for pointing me in the right direction with that build flag! Believe me, it’s going right straight into my troubleshooting toolbox.
Thanks again for the pointers, but as I’ve already mentioned the issue’s been fixed. I was accidentally throwing SDL into an unstable state because I was writing data outside of an array when building a texture. A few checks on the input for the concerned function cleared everything up.
… I don’t suppose anyone knows how to close a topic?