Norbert wrote: ↑February 11th, 2020, 12:27 pm
To replicate, use nothurtspikesmaybetrick.p1r from here.
Tab to the replay, then back to the title screen, then during one of the intro notes press Tab again to crash SDLPoP (works about 33-50% of the time).
Says "malloc(): smallbin double linked list corrupted".
Hey, this is odd: If I play back that file then SDLPoP will use PC Speaker sounds.
If I press Ctrl+R during that, then the rest of the game will use PC Speaker sounds as well!
The crash happens only if the intro music is played using the PC Speaker.
So this is really two bugs in one:
#1: SDLPoP switching to PC Speaker sounds. (Maybe that's how this p1r was recorded? But the sound_flags variable is not even saved in replays!)
#2: SDLPoP crashing if the PC Speaker version of the intro music is interrupted by Tab.
Norbert wrote: ↑February 11th, 2020, 12:27 pm
From what I've read, if a signal handler for SIGSEGV has been set by the application, additional actions are necessary for cores to dump.
SDLPoP doesn't set signal handlers, although SDL might do so.
A possible fix I found for #2 is to add a line to the beginning of start_replay()
Code: Select all
void start_replay() {
+ stop_sounds();
if (!enable_replay) return;
However, now I can't reproduce the bug anymore, not even if I undo this fix!
Maybe because I accidentally pressed Rebuild All in Dev-C++? (It's the equivalent of make clean + make.)
I'm also starting to figure out why #1 happens:
The file nothurtspikesmaybetrick.p1r contains a mod name: "Maze Of Persia".
Now, the load_all_sounds() function loads sounds differently if a custom levelset is in use.
The intention is that first it loads sounds from the mod folder, then it loads sounds from the SDLPoP data folder.
(Why? This was not needed for other DAT files.)
But what happens instead is that the first part (called "loads sounds from the mod folder") will somehow load sounds from the data/IBM_SND* folder!
Then the second part won't load any sounds because they are already loaded.
On a related note, open_dat() will never open a file from a mod folder indicated by a playback file, because mod_data_path is filled only in load_mod_options(), which is called only from pop_main() once at startup!
Therefore in the following line in open_dat():
Code: Select all
snprintf(filename_mod, sizeof(filename_mod), "%s/%s", mod_data_path, filename);
filename_mod will always start with "/", thus SDLPoP will look for the file in the root directory!
The solution I found is to add a line to apply_replay_options():
Code: Select all
+ load_mod_options();
reload_resources();
}
Somehow the non-empty mod_data_path will now prevent SDLPoP from using the data/IBM_SND* folder when it should use only the mod folder ("first part" above), even if "mods/Maze Of Persia" doesn't exist.
But I don't know why.
The file didn't exist in the root directory either, yet in that case SDLPoP behaved differently.
I might look into this another day, but not now, because one hour of debugging is more than enough for a day.
