[gens-sdl] EmuLoop: Save the rom_filename string directly instead of using c_str().
authorDavid Korth <gerbilsoft@gerbilsoft.com>
Mon, 7 Sep 2015 16:24:22 +0000 (12:24 -0400)
committerDavid Korth <gerbilsoft@gerbilsoft.com>
Mon, 7 Sep 2015 16:24:22 +0000 (12:24 -0400)
It seems that with gcc-5.x's "short string optimization", storing the
C string pointer instead of the entire C++ string causes random
corruption with filenames longer than the short string buffer.
It makes no sense, since both the rom_filename and c_str() values
show the same pointer, but rom_filename shows corruption while a
direct access to c_str() does not.

src/gens-sdl/EmuLoop.cpp

index d68a4ac..8a60620 100644 (file)
@@ -527,13 +527,17 @@ int EmuLoop::run(const Options *options)
        d->options = options;
        
        // Load the ROM image.
-       const char *rom_filename = options->rom_filename().c_str();
-       d->rom = new Rom(rom_filename);
+       // NOTE: If we get rom_filename().c_str(),
+       // random corruption happens with long filenames.
+       // This might be a result of gcc-5.x using
+       // "short string optimization".
+       string rom_filename = options->rom_filename();
+       d->rom = new Rom(rom_filename.c_str());
        if (!d->rom->isOpen()) {
                // Error opening the ROM.
                // TODO: Error code?
                fprintf(stderr, "Error opening ROM file %s: (TODO get error code)\n",
-                       rom_filename);
+                       rom_filename.c_str());
                delete d->rom;
                d->rom = nullptr;
                return EXIT_FAILURE;
@@ -548,8 +552,9 @@ int EmuLoop::run(const Options *options)
        if (!EmuContextFactory::isRomFormatSupported(d->rom)) {
                // ROM format is not supported.
                const char *rom_format = romFormatToString(d->rom->romFormat());
-               fprintf(stderr, "Error loading ROM file %s: ROM is in %s format.\nOnly plain binary and SMD-format ROMs are supported.\n",
-                       rom_filename, rom_format);
+               fprintf(stderr, "Error loading ROM file %s: ROM is in %s format.\n"
+                       "Only plain binary and SMD-format ROMs are supported.\n",
+                       rom_filename.c_str(), rom_format);
                return EXIT_FAILURE;
        }
 
@@ -557,8 +562,9 @@ int EmuLoop::run(const Options *options)
        if (!EmuContextFactory::isRomSystemSupported(d->rom)) {
                // System is not supported.
                const char *rom_sysId = sysIdToString(d->rom->sysId());
-               fprintf(stderr, "Error loading ROM file %s: ROM is for %s.\nOnly Mega Drive and Pico ROMs are supported.\n",
-                       rom_filename, rom_sysId);
+               fprintf(stderr, "Error loading ROM file %s: ROM is for %s.\n"
+                       "Only Mega Drive and Pico ROMs are supported.\n",
+                       rom_filename.c_str(), rom_sysId);
                return EXIT_FAILURE;
        }
 
@@ -577,14 +583,10 @@ int EmuLoop::run(const Options *options)
                // Error loading the ROM into EmuMD.
                // TODO: Error code?
                fprintf(stderr, "Error initializing EmuContext for %s: (TODO get error code)\n",
-                       rom_filename);
+                       rom_filename.c_str());
                return EXIT_FAILURE;
        }
 
-       // Done using rom_filename. NULL it out to prevent
-       // issues with Options possibly deleting the string.
-       rom_filename = nullptr;
-
        // Initialize the SDL handlers.
        d->sdlHandler = new SdlHandler();
        if (d->sdlHandler->init_video() < 0)