t-paul/kcemu

kcemu does not start

Closed this issue · 2 comments

w8970 commented

After the trick with autoreconf (see #2) I was able to build the SW.

Then I did "make install" and tried to run it by:
$ ~/bin/kcemu
can't open file '/home/erik/share/kcemu/roms/kc85/!'

But dir exists and has content:

$ ls /home/erik/share/kcemu/roms/kc85/
basic_c0.853 caos33.853 caos43c.855 caos46c.855 caos__e0.852 floppy20.rom floppy33.853 m012.rom m052.rom pi88_sw.853 vdip21.rom
basic_c0.854 caos34.853 caos43e.855 caos46e.855 caos__e0.853 floppy30.rom floppy33.854 m026.rom m900.rom pi88_ws.853
basic_c0.855 caos41c.854 caos45c.855 caos__c0.854 caos__e0.854 floppy31.rom hc900.852 m027.rom m901.rom user46.855
basicusb.855 caos41e.854 caos45e.855 caos__c0.855 caos__e0.855 floppy32.rom m006.rom m033.rom pi88_ge.853 vdip12.rom

It seems the same bug, a Debian user already found some years ago:
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=970666

What can I do?

The error seems to be in memory.cc around line 370.

A pointer to the ROM file name is stored in romfile.

Thread 1 "kcemu" hit Breakpoint 1.1, Memory::load_rom (key=0x5555556822a1 "rom_system_1", buf=0x555556769530) at memory.cc:318
318     {
(gdb) display romfile
1: romfile = 0x7fffffffcb00 "0\313\377\377\377\177"
(gdb) n
319       DBG(1, form("KCemu/Memory/load_rom",
1: romfile = 0x7fffffffcb00 "0\313\377\377\377\177"
(gdb) 
323       SystemType *system = Preferences::instance()->get_system_type();
1: romfile = 0x7fffffffcb00 "0\313\377\377\377\177"
(gdb) 
324       const SystemROM *rom = system->get_rom(key);
1: romfile = 0x7fffffffcb00 "0\313\377\377\377\177"
(gdb) 
325       if (rom == NULL)
1: romfile = 0x7fffffffcb00 "0\313\377\377\377\177"
(gdb) 
331       const char *romfile = Preferences::instance()->get_string_value(key, NULL);
1: romfile = 0x7fffffffcb00 "0\313\377\377\377\177"
(gdb) 
333       if (romfile == NULL)
1: romfile = 0x0
(gdb) 
335           DBG(1, form("KCemu/Memory/load_rom",
1: romfile = 0x0
(gdb) 
354       if (romfile == NULL)
1: romfile = 0x0
(gdb) 
356           const ROMEntry * rom_entry = rom->get_default_rom();
1: romfile = 0x0
(gdb) 
357           if (rom_entry == NULL)
1: romfile = 0x0
(gdb) 
360           romfile = rom_entry->get_filename().c_str();
1: romfile = 0x0
(gdb) 
361           DBG(1, form("KCemu/Memory/load_rom",
1: romfile = 0x7fffffffcba0 "poly880a.rom"
(gdb) 
366       string rompath; // must be still in scope when calling load_rom() below...
1: romfile = 0x7fffffffcba0 "poly880a.rom"
(gdb) 
367       if (!sys_isabsolutepath(romfile))
1: romfile = 0x7fffffffcba0 "poly880a.rom"
(gdb) 
369           string datadir(kcemu_datadir);
1: romfile = 0x7fffffffcba0 "poly880a.rom"
(gdb) 
370           string romdir = datadir + system->get_rom_directory() + "/";
1: romfile = 0x7fffffffcba0 "poly880a.rom"
(gdb) 

This buffer gets overwritten as a side effect of the statement in line 370.

371           rompath = romdir + romfile;
1: romfile = 0x7fffffffcba0 ""
(gdb) 
372           romfile = rompath.c_str();
1: romfile = 0x7fffffffcba0 ""
(gdb) 
373           DBG(1, form("KCemu/Memory/load_rom",
1: romfile = 0x55555676bde0 "/usr/share/kcemu/roms/poly880/"
(gdb) 
376         }
1: romfile = 0x55555676bde0 "/usr/share/kcemu/roms/poly880/"
(gdb) 
378       return load_rom(romfile, buf, rom->get_size(), rom->is_mandatory());
1: romfile = 0x55555676bde0 "/usr/share/kcemu/roms/poly880/"

Hi Mario,

thank you for analyzing. It seems to be a quite strange string and pointer handling in this file. :-O

I assume that "romfile = rompath.c_str();" becomes invalid because of optimizations newer compiler will do on "rompath", so the comment "string rompath; // must be still in scope when calling load_rom() below..." is not valid anymore.

If the whole code is full of such "strange handling" it will not run successfully anymore and could be painful to find and fix.