• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

TFS 1.X+ Segmentation fault (Accessing storage value)

Albert José

Rambocop Infernus
Joined
Jun 10, 2008
Messages
87
Solutions
1
Reaction score
13
Location
Portugal
GitHub
albertjose
Hi fellas,

My server crashed unexpectedly the other day, and I'm stumped as to why. After checking out the crash log, it seems like it could be related to a storage value.

Any thoughts on how to fix this? I saw a reference to a onDeath creature event, but I don't know if can assume that the crashlog shows me the tree of execution of my code:
Bash:
#15 0x000055583810a3e6 in CreatureEvent::executeOnDeath(Creature*, Item*, Creature*, Creature*, bool, bool) ()
No symbol table info available.
#16 0x00005558380fcea7 in Creature::dropCorpse(Creature*, Creature*, bool, bool) ()
No symbol table info available.
#17 0x00005558380fca7a in Creature::onDeath() ()
No symbol table info available.

Bash:
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `./tfs'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00005558380acef4 in std::less<unsigned int>::operator()(unsigned int const&, unsigned int const&) const ()
[Current thread is 1 (Thread 0x7f16ce930700 (LWP 1523195))]
(gdb) bt full
#0  0x00005558380acef4 in std::less<unsigned int>::operator()(unsigned int const&, unsigned int const&) const ()
No symbol table info available.
#1  0x00005558383b1be7 in std::_Rb_tree<unsigned int, std::pair<unsigned int const, int>, std::_Select1st<std::pair<unsigned int const, int> >, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, int> > >::_M_lower_bound(std::_Rb_tree_node<std::pair<unsigned int const, int> > const*, std::_Rb_tree_node_base const*, unsigned int const&) const ()
No symbol table info available.
#2  0x00005558383ae4d1 in std::_Rb_tree<unsigned int, std::pair<unsigned int const, int>, std::_Select1st<std::pair<unsigned int const, int> >, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, int> > >::find(unsigned int const&) const ()
No symbol table info available.
#3  0x00005558383abe65 in std::map<unsigned int, int, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, int> > >::find(unsigned int const&) const ()
No symbol table info available.
#4  0x000055583839cbeb in Player::getStorageValue(unsigned int, int&) const ()
No symbol table info available.
#5  0x000055583839cb4f in Player::addStorageValue(unsigned int, int, bool) ()
No symbol table info available.
#6  0x000055583830797a in LuaScriptInterface::luaPlayerSetStorageValue(lua_State*) ()
No symbol table info available.
#7  0x00007f16cfe5af2e in ?? () from /lib/x86_64-linux-gnu/liblua5.2.so.0
No symbol table info available.
#8  0x00007f16cfe66cfc in ?? () from /lib/x86_64-linux-gnu/liblua5.2.so.0
No symbol table info available.
#9  0x00007f16cfe5b2d8 in ?? () from /lib/x86_64-linux-gnu/liblua5.2.so.0
No symbol table info available.
#10 0x00007f16cfe5a84f in ?? () from /lib/x86_64-linux-gnu/liblua5.2.so.0
No symbol table info available.
#11 0x00007f16cfe5b51f in ?? () from /lib/x86_64-linux-gnu/liblua5.2.so.0
No symbol table info available.
#12 0x00007f16cfe57481 in lua_pcallk () from /lib/x86_64-linux-gnu/liblua5.2.so.0
No symbol table info available.
#13 0x000055583827a1f2 in LuaScriptInterface::protectedCall(lua_State*, int, int) ()
No symbol table info available.
#14 0x000055583827b33e in LuaScriptInterface::callFunction(int) ()
No symbol table info available.
#15 0x000055583810a3e6 in CreatureEvent::executeOnDeath(Creature*, Item*, Creature*, Creature*, bool, bool) ()
No symbol table info available.
#16 0x00005558380fcea7 in Creature::dropCorpse(Creature*, Creature*, bool, bool) ()
No symbol table info available.
#17 0x00005558380fca7a in Creature::onDeath() ()
No symbol table info available.
#18 0x0000555838125046 in Game::executeDeath(unsigned int) ()
No symbol table info available.
#19 0x00005558380bfb8a in void std::__invoke_impl<void, void (Game::*&)(unsigned int), Game*&, unsigned int&>(std::__invoke_memfun_deref, void (Game::*&)(unsigned int), Game*&, unsigned int&) ()
No symbol table info available.
#20 0x00005558380bf937 in std::__invoke_result<void (Game::*&)(unsigned int), Game*&, unsigned int&>::type std::__invoke<void (Game::*&)(unsigned int), Game*&, unsigned int&>(void (Game::*&)(unsigned int), Game*&, unsigned int&) ()
No symbol table info available.
#21 0x00005558380bef05 in void std::_Bind<void (Game::*(Game*, unsigned int))(unsigned int)>::__call<void, , 0ul, 1ul>(std::tuple<>&&, std::_Index_tuple<0ul, 1ul>) ()
No symbol table info available.
#22 0x00005558380be5ea in void std::_Bind<void (Game::*(Game*, unsigned int))(unsigned int)>::operator()<, void>() ()
No symbol table info available.
#23 0x00005558380bd528 in void std::__invoke_impl<void, std::_Bind<void (Game::*(Game*, unsigned int))(unsigned int)>&>(std::__invoke_other, std::_Bind<void (Game::*(Game*, unsigned int))(unsigned int)>&) ()
No symbol table info available.
#24 0x00005558380baef4 in std::enable_if<is_invocable_r_v<void, std::_Bind<void (Game::*(Game*, unsigned int))(unsigned int)>&>, void>::type std::__invoke_r<void, std::_Bind<void (Game::*(Game*, unsigned int))(unsigned int)>&>(std::_Bind<void (Game::*(Game*, unsigned int))(unsigned int)>&) ()
No symbol table info available.
#25 0x00005558380b9350 in std::_Function_handler<void (), std::_Bind<void (Game::*(Game*, unsigned int))(unsigned int)> >::_M_invoke(std::_Any_data const&)
    ()
No symbol table info available.
#26 0x000055583843722a in std::function<void ()>::operator()() const ()
No symbol table info available.
#27 0x0000555838436b14 in Task::operator()() ()
No symbol table info available.
#28 0x0000555838436e48 in Dispatcher::threadMain() ()
No symbol table info available.
#29 0x000055583838d4b9 in void std::__invoke_impl<void, void (Dispatcher::*)(), Dispatcher*>(std::__invoke_memfun_deref, void (Dispatcher::*&&)(), Dispatcher*&&) ()
No symbol table info available.
#30 0x000055583838d174 in std::__invoke_result<void (Dispatcher::*)(), Dispatcher*>::type std::__invoke<void (Dispatcher::*)(), Dispatcher*>(void (Dispatcher::*&&)(), Dispatcher*&&) ()
No symbol table info available.
#31 0x000055583838ccad in void std::thread::_Invoker<std::tuple<void (Dispatcher::*)(), Dispatcher*> >::_M_invoke<0ul, 1ul>(std::_Index_tuple<0ul, 1ul>) ()
No symbol table info available.
#32 0x000055583838c900 in std::thread::_Invoker<std::tuple<void (Dispatcher::*)(), Dispatcher*> >::operator()() ()
#33 0x000055583838c3b4 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (Dispatcher::*)(), Dispatcher*> > >::_M_run() ()
No symbol table info available.
#34 0x00007f16cf93bed0 in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6
No symbol table info available.
#35 0x00007f16d035fea7 in start_thread (arg=<optimized out>) at pthread_create.c:477
        ret = <optimized out>
        pd = <optimized out>
        unwind_buf = {cancel_jmp_buf = {{jmp_buf = {139735931750144, 5774162317471215587, 140736782396942, 140736782396943, 139735931748288, 8396800,
                -5905222772085133341, -5905254426019663901}, mask_was_saved = 0}}, priv = {pad = {0x0, 0x0, 0x0, 0x0}, data = {prev = 0x0, cleanup = 0x0,
              canceltype = 0}}}
        not_first_call = 0
#36 0x00007f16cf634a6f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
 
Last edited:
I have never used one of those debug logs like you have posted, but following it's call stack, it appears as though once there was a death, that the method for "Game" was called, and it was looking for a uint that didn't exist, or its value wasn't of uint (possible negative).

I could be very wrong though.

Is there anyway you could try to force it to happen again, and monitor which scripts are being used (run test server with bare minimum scripts), possibly adding them back in one at a time with a print or so here and there to try to narrow down the problem?
 
The problem is that this crash happened 5 days ago and didn't happen again, I tried to simulate the problem by accessing a character's storage right after his death, while he was still logged out, but the error appears as a normal nil access on the side from lua, without generating a crash as happened in this stack.
 
You must show all onDeath scripts/revscripts that set a storage value...
(you can scan all of your data directory for "onDeath")
 
I still haven't been able to solve the problem, I created a function to set storages values, always checking if the player exists before calling and replacing all direct calls player:setStorageValue... with the function I created, but I still have the same problem, does anyone have any other tips?

Lua:
function doPlayerSetStorageValue(cid, key, value)
    local player = Player(cid)
    if player == nil then
        return false
    end

    return player:setStorageValue(key, value)
end

There is an example of onDeath using this new function:
Lua:
local bossDeath = CreatureEvent("demonOakDeath")
function bossDeath.onDeath(creature, corpse, killer, mostDamageKiller)
    if not creature or not creature:isMonster() then
        return true
    end

    if not currentBossPlayer then
        return true
    end

    local player = Player(currentBossPlayer)
    if not player then
        return true
    end

    doPlayerSetStorageValue(player, Storage.DemonOak.DefeatedBoss, 1)
    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'Congratulations! You have defeated the Ashmunrah, now hit the demon oak with the axe to finish the quest.')
    return true
end

bossDeath:register()
 
Back
Top