DFHack / dfhack

Memory hacking library for Dwarf Fortress and a set of tools that use it
Other
1.86k stars 470 forks source link

Crashing on "Save and return to title screen" when a mod using add-spatter plugin is loaded #4794

Closed Deon-DF closed 1 month ago

Deon-DF commented 2 months ago

When no mods are loaded, saving and loading works fine.

When a mod that uses reactions that utilize add-spatter plugin is loaded (without actually using plugin functionality in game, just generate a world and start fortress mode), the game crashes on "Save and go to title". Reproduced 100%. The save still happens though.

Mod: https://steamcommunity.com/sharedfiles/filedetails/?id=3271054331 Non-beta version of the game and latest Steam build of DFHack is used.

Crash log: 0> Dwarf_Fortress!std::_Init_locks::operator=+0x810A76 1> Dwarf_Fortress!std::_Init_locks::operator=+0x810BE9 2> KERNELBASE!UnhandledExceptionFilter+0x1EC 3> ntdll!memcpy+0x2BBD 4> ntdll!_C_specific_handler+0x97 5> ntdll!_chkstk+0x12F 6> ntdll!RtlFindCharInUnicodeString+0xA96 7> ntdll!KiUserExceptionDispatcher+0x2E 8> dfhooks_dfhack!DFHack::VMethodInterposeLinkBase::find_child_hosts+0xAF 9> dfhooks_dfhack!DFHack::VMethodInterposeLinkBase::apply+0x299 10> add_spatter_plug!plugin_load_world_data+0x3B 11> dfhooks_dfhack!DFHack::PluginManager::doLoadWorldData+0x94 12> dfhooks_dfhack!DFHack::Core::onStateChange+0x340 13> dfhooks_dfhack!DFHack::Core::doUpdate+0x25B 14> dfhooks_dfhack!DFHack::Core::Update+0x86 15> dfhooks!dfhooks_update+0x468E 16> Dwarf_Fortress!std::_Init_locks::operator=+0x6438F3 17> Dwarf_Fortress!std::_Init_locks::operator=+0x644C49 18> SDL2!SDL_DYNAPI_entry+0x799D7 19> SDL2!SDL_DYNAPI_entry+0x12EEDE 20> ucrtbase!recalloc+0xA3 21> KERNEL32!BaseThreadInitThunk+0x1D 22> ntdll!RtlUserThreadStart+0x28

glolsh commented 2 months ago

Second to this. Also happens when you load game second time.

  1. Launch game
  2. Load game
  3. Exit to title
  4. Load game again
lethosor commented 2 months ago

Also happens when you load game second time.

Just to clarify: Is this made possible by not saving the first time?

glolsh commented 2 months ago

@lethosor In my case you need something to load. So having 1 save is fine. Once you have it - case can be reproduced infinitely just by loading games and quitting to title. Sorry if I misunderstood point of your question.

lethosor commented 2 months ago

I just don't understand how it could crash when loading a second time (in a single game session) if it crashes when saving the first time.

Deon-DF commented 2 months ago

It is possible we have different scenarios. For me it crashes the 1st time.

glolsh commented 2 months ago

@Deon-DF So you basically can't play? With Poisoner workshop?

Deon-DF commented 2 months ago

That is not true. The game crashes on exit to menu, but save happens. Sorry for not mentioning it earlier, I will update the report.

glolsh commented 2 months ago

So in my case I basically don't use "save and go to title". I use "save and continue". Well, so um we can disregard that in my case. Try to follow this case.

  1. Launch Dwarf Fortress GAME
  2. Load you save
  3. Exit to title without saving
  4. Load you save again
myk002 commented 1 month ago

I can easily reproduce the crash in current code in DF 51.01. I cannot reproduce the problem in DF 50.12. I suspect this might be an unintended side effect of our vtable handling in 50.13-r3.

I get a similar stack trace for the crash:

Detected spatter add reactions - enabling plugin.
[DFHack]# 
          Thread 3 "dwarfort" received signal SIGSEGV, Segmentation fault.
                                                                          [Switching to Thread 0x7ffff5bfe6c0 (LWP 22807)]
DFHack::VMethodInterposeLinkBase::get_first_interpose (this=this@entry=0x7ffff210a120 <item_hook::interpose_isImprovable>, 
    id=id@entry=0x7fffeeb0f9a0 <df::item_windowst::_identity>) at /home/myk/src/dfhack/library/VTableInterpose.cpp:334
334         if (item->host != id)

and inspecting the item variable, we see:

(gdb) print item
$1 = (DFHack::VMethodInterposeLinkBase *) 0x0

Earlier in the function, we have

    auto item = id->interpose_list[vmethod_idx];
    if (!item)
        return NULL;

so I'm not sure exactly what's going on here. Need to dig in deeper.

myk002 commented 1 month ago

DFHack 50.13-r2.1 does not exhibit the crash, so it seems like a regression in 50.13-r3. @ab9rf does this happen on Windows?

savegame:

add_spatter_crash.zip

mod:

poisoner_mod.zip

repro procedure as in https://github.com/DFHack/dfhack/issues/4794#issuecomment-2217182399