Minetest: Crash when calling remove_detached_inventory during mod load

Created on 20 Aug 2019  路  3Comments  路  Source: minetest/minetest

Minetest version
5.0.1
OS / Hardware

Operating system: Windows 10 Home
CPU: Intel i7-3770K @ 3.5GHz, 8.00 GB ram

Summary

It appears that attempting to call minetest.remove_detached_inventory on a detached inventory while mods are still loading will cause an immediate crash to desktop, with no debugging output recorded about any further details.

Steps to reproduce

A mod with the following init.lua reliably reproduces the problem:

local test = minetest.create_detached_inventory("test", {})
test:set_size("main", 1)

minetest.remove_detached_inventory("test") -- this kills the Minetest

minetest.after(5, function()
    local success = minetest.remove_detached_inventory("test") -- this one works fine though
    minetest.chat_send_all("Success: " .. tostring(success))
end)

Commenting out the first detached causes the game to load without crashing, and five seconds later success at removing the detached inventory is reported.

I discovered this issue when attempting to override the behaviour of the "creative" mod's trash inventory in Digtron 2.0. I wanted to catch certain items being placed in the trash so I could read metadata off of their itemstacks and clean up some records tracking them, so I tried deleting and recreating the creative_trash detached inventory with additional code in its on_put callback. I can put this into an "after" function as a workaround (as illustrated in this test mod), can't think of any other way to do it unfortunately.

Unconfirmed bug

Most helpful comment

1) Where do you guys get such ideas from? Like seriously?
2) gdb minetest

Thread 1 "minetest_occlus" received signal SIGSEGV, Segmentation fault.
0x0000555555be056a in ServerEnvironment::getPlayer(char const*) ()
(gdb) bt
#0  0x0000555555be056a in ServerEnvironment::getPlayer(char const*) ()
#1  0x0000555555bc5ef5 in Server::removeDetachedInventory(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) ()
#2  0x000055555599850b in ModApiInventory::l_remove_detached_inventory_raw(lua_State*) ()

EDIT: As a workaround, you can read the definition from minetest.detached_inventories[name] and call minetest.create_detached_inventory() again to override the fields. Or just override the table directly because Minetest does not keep any definition data in C++.

All 3 comments

1) Where do you guys get such ideas from? Like seriously?
2) gdb minetest

Thread 1 "minetest_occlus" received signal SIGSEGV, Segmentation fault.
0x0000555555be056a in ServerEnvironment::getPlayer(char const*) ()
(gdb) bt
#0  0x0000555555be056a in ServerEnvironment::getPlayer(char const*) ()
#1  0x0000555555bc5ef5 in Server::removeDetachedInventory(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) ()
#2  0x000055555599850b in ModApiInventory::l_remove_detached_inventory_raw(lua_State*) ()

EDIT: As a workaround, you can read the definition from minetest.detached_inventories[name] and call minetest.create_detached_inventory() again to override the fields. Or just override the table directly because Minetest does not keep any definition data in C++.

b8131c3
Also includes a fix for calling the function with a player name.

Ah, excellent, I'll be able to copy the original on_put function pointer from the existing definition and call it after I do my Digtron-specific stuff. That'll be more robust against potential future changes in the creative mod.

I like to think that I haven't really been _seriously_ modding until I discover a new issue I can file here. Just wait until I test what happens when I try overriding an ObjectRef's remove() method, I'm sure that's not going to work at all like I'm hoping. :)

Was this page helpful?
0 / 5 - 0 ratings