• 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 0.X Translating the Crashing Log

ThaLeeeS

Member
Joined
Oct 4, 2009
Messages
189
Reaction score
7
Location
Brazil
Hi everybody,

I diagnosed a random crash in TFS 0.3.6 compiled distro of Ubuntu 16.04.
Could someone help me to find a way to solve the crash by understanding the gdb log?

C++:
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `./theforgottenserver'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x000000000047a95d in Game::addCreatureHealth (this=this@entry=0x8ac540 <g_game>, list=..., target=target@entry=0x7fa5c2114370) at game.cpp:4752
4752            if((player = (*it)->getPlayer()))
[Current thread is 1 (Thread 0x7fa5d8d78700 (LWP 7754))]
(gdb) bt full
#0  0x000000000047a95d in Game::addCreatureHealth (this=this@entry=0x8ac540 <g_game>, list=..., target=target@entry=0x7fa5c2114370) at game.cpp:4752
        it =
        player = <optimized out>
#1  0x00000000004843a7 in Game::combatChangeHealth (this=0x8ac540 <g_game>, combatType=COMBAT_PHYSICALDAMAGE, attacker=attacker@entry=0x7fa5cbac1830, target=target@entry=0x7fa5c2114370,
    healthChange=<optimized out>, hitEffect=MAGIC_EFFECT_UNKNOWN, hitColor=TEXTCOLOR_UNKNOWN, force=false) at game.cpp:4530
        deny = <optimized out>
        statsChangeEvents = {<std::__cxx11::_List_base<CreatureEvent*, std::allocator<CreatureEvent*> >> = {
            _M_impl = {<std::allocator<std::_List_node<CreatureEvent*> >> = {<__gnu_cxx::new_allocator<std::_List_node<CreatureEvent*> >> = {<No data fields>}, <No data fields>},
              _M_node = {<std::__detail::_List_node_base> = {_M_next = 0x7fa5ab755bc0, _M_prev = 0x7fa5c179fac0}, _M_data = 2}}}, <No data fields>}
        textColor = <optimized out>
        magicEffect = <optimized out>
        list = @0x7fa5c7bfb3e0: {<std::__cxx11::_List_base<Creature*, std::allocator<Creature*> >> = {
            _M_impl = {<std::allocator<std::_List_node<Creature*> >> = {<__gnu_cxx::new_allocator<std::_List_node<Creature*> >> = {<No data fields>}, <No data fields>},
              _M_node = {<std::__detail::_List_node_base> = {_M_next = 0x7fa5c7e3dbd0, _M_prev = 0x7fa5c7e3dbe0}, _M_data = 21}}}, <No data fields>}
        damage = 989
        targetPos = @0x7fa5d8d77370: {x = 1041, y = 1031, z = 6}
#2  0x000000000042f213 in Combat::CombatHealthFunc (caster=caster@entry=0x7fa5cbac1830, target=0x7fa5c2114370, params=..., data=data@entry=0x7fa5d8d77540) at combat.cpp:577
        change = -1320
#3  0x0000000000431ed5 in Combat::CombatFunc (caster=caster@entry=0x7fa5cbac1830, pos=..., area=<optimized out>, params=...,
    func=func@entry=0x42f116 <Combat::CombatHealthFunc(Creature*, Creature*, CombatParams const&, void*)>, data=data@entry=0x7fa5d8d77540) at combat.cpp:809
        cit =
        cend =
        skip = true
        it =
        tileList = {<std::__cxx11::_List_base<Tile*, std::allocator<Tile*> >> = {
            _M_impl = {<std::allocator<std::_List_node<Tile*> >> = {<__gnu_cxx::new_allocator<std::_List_node<Tile*> >> = {<No data fields>}, <No data fields>},
              _M_node = {<std::__detail::_List_node_base> = {_M_next = 0x7fa5c84c5fd0, _M_prev = 0x7fa5c84c5fd0}, _M_data = 1}}}, <No data fields>}
        var = 0x7fa5d8d77540
        maxX = <optimized out>
        maxY = <optimized out>
        diff = <optimized out>
        list = {<std::__cxx11::_List_base<Creature*, std::allocator<Creature*> >> = {
            _M_impl = {<std::allocator<std::_List_node<Creature*> >> = {<__gnu_cxx::new_allocator<std::_List_node<Creature*> >> = {<No data fields>}, <No data fields>},
              _M_node = {<std::__detail::_List_node_base> = {_M_next = 0x7fa5c7b6bf70, _M_prev = 0x7fa5aaadf560}, _M_data = 21}}}, <No data fields>}
        tile = 0x7fa5a0015c70
#4  0x0000000000431fe9 in Combat::doCombatHealth (caster=caster@entry=0x7fa5cbac1830, pos=..., area=<optimized out>, minChange=<optimized out>, maxChange=<optimized out>, params=...) at combat.cpp:881
        var = {minChange = -1150, maxChange = -1725, change = -1320}
#5  0x0000000000432dbe in Combat::doCombat (this=this@entry=0x7fa5c7b56b40, caster=caster@entry=0x7fa5cbac1830, pos=...) at combat.cpp:846
        minChange = -1150
        maxChange = -1725
#6  0x000000000051a08c in LuaScriptInterface::luaDoCombat (L=0x7fa5c7817050) at luascript.cpp:6198
        var = {type = VARIANT_POSITION, text = "", pos = {<Position> = {x = 1041, y = 1031, z = 6}, stackpos = 0}, number = 0}
---Type <return> to continue, or q <return> to quit---
        combatId = 347
        cid = <optimized out>
        creature = 0x7fa5cbac1830
        __FUNCTION__ = "luaDoCombat"
        combat = 0x7fa5c7b56b40
#7  0x00007fa5ddc98320 in ?? () from /usr/lib/x86_64-linux-gnu/liblua5.1.so.0
No symbol table info available.
#8  0x00007fa5ddca2eea in ?? () from /usr/lib/x86_64-linux-gnu/liblua5.1.so.0
No symbol table info available.
#9  0x00007fa5ddc9877d in ?? () from /usr/lib/x86_64-linux-gnu/liblua5.1.so.0
No symbol table info available.
#10 0x00007fa5ddc97a5e in ?? () from /usr/lib/x86_64-linux-gnu/liblua5.1.so.0
No symbol table info available.
#11 0x00007fa5ddc988eb in ?? () from /usr/lib/x86_64-linux-gnu/liblua5.1.so.0
No symbol table info available.
#12 0x00007fa5ddc943a8 in lua_pcall () from /usr/lib/x86_64-linux-gnu/liblua5.1.so.0
No symbol table info available.
#13 0x000000000050bed3 in LuaScriptInterface::callFunction (this=this@entry=0x7fa5c8036d80, params=1) at luascript.cpp:932
        size = 6
        handler = 5
        result = false
#14 0x000000000050c0f2 in LuaScriptInterface::executeTimer (this=0x7fa5c8036d80, eventIndex=1897) at luascript.cpp:886
        it = {first = 1897, second = {scriptId = 0, function = 103, parameters = {<std::__cxx11::_List_base<int, std::allocator<int> >> = {
                _M_impl = {<std::allocator<std::_List_node<int> >> = {<__gnu_cxx::new_allocator<std::_List_node<int> >> = {<No data fields>}, <No data fields>},
                  _M_node = {<std::__detail::_List_node_base> = {_M_next = , _M_prev = }, _M_data = 1}}}, <No data fields>}}}
#15 0x000000000052ef4a in boost::_mfi::mf1<void, LuaScriptInterface, unsigned int>::operator() (a1=<optimized out>, p=<optimized out>, this=<optimized out>)
    at /usr/include/boost/bind/mem_fn_template.hpp:165
No locals.
#16 boost::_bi::list2<boost::_bi::value<LuaScriptInterface*>, boost::_bi::value<unsigned int> >::operator()<boost::_mfi::mf1<void, LuaScriptInterface, unsigned int>, boost::_bi::list0> (
    a=<synthetic pointer>, f=..., this=<optimized out>) at /usr/include/boost/bind/bind.hpp:313
No locals.
#17 boost::_bi::bind_t<void, boost::_mfi::mf1<void, LuaScriptInterface, unsigned int>, boost::_bi::list2<boost::_bi::value<LuaScriptInterface*>, boost::_bi::value<unsigned int> > >::operator() (
    this=<optimized out>) at /usr/include/boost/bind/bind_template.hpp:20
No locals.
#18 boost::detail::function::void_function_obj_invoker0<boost::_bi::bind_t<void, boost::_mfi::mf1<void, LuaScriptInterface, unsigned int>, boost::_bi::list2<boost::_bi::value<LuaScriptInterface*>, boost::_bi::value<unsigned int> > >, void>::invoke (function_obj_ptr=...) at /usr/include/boost/function/function_template.hpp:159
        f = <optimized out>
#19 0x00000000005eada2 in OutputMessagePool::getInstance () at outputmessage.h:153
        instance = warning: can't find linker symbol for virtual table for `OutputMessagePool' value
warning:   found `typeinfo name for boost::_bi::bind_t<void, boost::_mfi::mf1<void, OutputMessagePool, OutputMessage*>, boost::_bi::list2<boost::_bi::value<OutputMessagePool*>, boost::_bi::value<OutputMessage*> > >' instead
{
          _vptr.OutputMessagePool = 0x62ced8 <typeinfo name for boost::_bi::bind_t<void, boost::_mfi::mf1<void, OutputMessagePool, OutputMessage*>, boost::_bi::list2<boost::_bi::value<OutputMessagePool*>, boost::_bi::value<OutputMessage*> > >+88>, m_autoSend = {<std::__cxx11::_List_base<boost::shared_ptr<OutputMessage>, std::allocator<boost::shared_ptr<OutputMessage> > >> = {
              _M_impl = {<std::allocator<std::_List_node<boost::shared_ptr<OutputMessage> > >> = {<__gnu_cxx::new_allocator<std::_List_node<boost::shared_ptr<OutputMessage> > >> = {<No data fields>}, <No ---Type <return> to continue, or q <return> to quit---
data fields>}, _M_node = {<std::__detail::_List_node_base> = {_M_next = 0x7fa5c79ef080, _M_prev = 0x7fa5c7a08320}, _M_data = 4}}}, <No data fields>},
          m_addQueue = {<std::__cxx11::_List_base<boost::shared_ptr<OutputMessage>, std::allocator<boost::shared_ptr<OutputMessage> > >> = {
              _M_impl = {<std::allocator<std::_List_node<boost::shared_ptr<OutputMessage> > >> = {<__gnu_cxx::new_allocator<std::_List_node<boost::shared_ptr<OutputMessage> > >> = {<No data fields>}, <No data fields>}, _M_node = {<std::__detail::_List_node_base> = {_M_next = 0x89dfa0 <OutputMessagePool::getInstance()::instance+32>, _M_prev = 0x89dfa0 <OutputMessagePool::getInstance()::instance+32>},
                  _M_data = 0}}}, <No data fields>}, m_outputMessages = {<std::__cxx11::_List_base<OutputMessage*, std::allocator<OutputMessage*> >> = {
              _M_impl = {<std::allocator<std::_List_node<OutputMessage*> >> = {<__gnu_cxx::new_allocator<std::_List_node<OutputMessage*> >> = {<No data fields>}, <No data fields>},
                _M_node = {<std::__detail::_List_node_base> = {_M_next = 0x7fa5d4004510, _M_prev = 0x7fa5c12adc70}, _M_data = 94}}}, <No data fields>},
          m_allMessages = {<std::__cxx11::_List_base<OutputMessage*, std::allocator<OutputMessage*> >> = {
              _M_impl = {<std::allocator<std::_List_node<OutputMessage*> >> = {<__gnu_cxx::new_allocator<std::_List_node<OutputMessage*> >> = {<No data fields>}, <No data fields>},
                _M_node = {<std::__detail::_List_node_base> = {_M_next = 0x89dfd0 <OutputMessagePool::getInstance()::instance+80>, _M_prev = 0x89dfd0 <OutputMessagePool::getInstance()::instance+80>},
                  _M_data = 0}}}, <No data fields>}, m_outputPoolLock = {m = {__data = {__lock = 0, __count = 0, __owner = 0, __nusers = 0, __kind = 1, __spins = 0, __elision = 0, __list = {
                  __prev = 0x0, __next = 0x0}}, __size = '\000' <repeats 16 times>, "\001", '\000' <repeats 22 times>, __align = 0}}, m_frameTime = 1533409032716, m_shutdown = false}
#20 Dispatcher::dispatcherThread (p=0x89dec0 <Dispatcher::getInstance()::dispatcher>) at tasks.cpp:70
        task = 0x7fa5c18432c0
        dispatcher = 0x89dec0 <Dispatcher::getInstance()::dispatcher>
        outputPool = <optimized out>
        taskLockUnique = {m = 0x89dec8 <Dispatcher::getInstance()::dispatcher+8>, is_locked = false}
#21 0x00000000005c62c0 in __static_initialization_and_destruction_0 (__priority=65535, __initialize_p=1) at /usr/include/boost/asio/io_service.hpp:759
No locals.
#22 _GLOBAL__sub_I__ZN9Scheduler13m_threadStateE () at scheduler.cpp:167
No locals.
#23 0x0000000000000000 in ?? ()
No symbol table info available.

Thank you
 
The gdb log tells you what happened: Program terminated with signal SIGSEGV, Segmentation fault.

A segmentation fault can happen when dereferencing a null-pointer, which looks to be the case here:
Code:
#0  0x000000000047a95d in Game::addCreatureHealth (this=this@entry=0x8ac540 <g_game>, list=..., target=target@entry=0x7fa5c2114370) at game.cpp:4752
4752            if((player = (*it)->getPlayer()))

-> dereferences the pointer (*it) so it can call getPlayer(). If (*it) points to invalid memory, then the dereference will cause a segmentation fault.

You could check that (*it) isn't null before dereferencing it, but that's only helpful if the pointer is null and not pointing at garbage memory:
Code:
...
if ((*it) == nullptr) {
    continue;
}

if((player = (*it)->getPlayer()))
...

However, like I said, if (*it) isn't null and it's just pointing at garbage memory, then the condition will fail and you'll still get a segmentation fault. To solve that, you should figure out why (*it) is invalid. A quick look at the source and it looks like it is an iterator through spectators, so it's likely that you have a race condition somewhere.
 
Hi, thanks for the assistance!

I added the (*it) validator and compiled it. Let's see if this issue will come up again.

I also noticed that this problem is related with player/summon dies.

I will keep this thread updated on when I get more info.
 
Hi @Jo3Bingham

No more crashing like the above crash log. However a new random crash starts to happening. Have you any ideia?

Code:
Game::internalCreatureChangeVisible (this=<optimized out>, creature=0x7fa5c2114370, visible=VISIBLE_NONE) at game.cpp:4358
        list = @0x100: <error reading variable>
        it =
        tmpPlayer = 0x0

Thanks!
 
Code:
list = @0x100: <error reading variable>
That's not good. Looking at the sources again here, list is the return from getSpectators(); which was the same core issue from your original post. Some change you've made is interfering with getSpectators(), assuming you've made engine changes as I doubt these issues would be happening with an unmodified 0.3.6 distro.
 
Thank you for answering.

The weird thing is that those methods are not modified. The only modification I've made is in luascript, in other words, I added a custom method to validate some player info, which I think should not causing the issue.

I checked the possibilities of call that method of "invisible" feature and I noticed it can be called in monsters who has invisible defense condition or in ghost admin command. I really do not know why it crashes randomly :(

Is possible the compiler libraries causing some bug?
Could I validate the variable list in this case?
 
Last edited:

Similar threads

Back
Top