Search code examples
c++gdbstdmapsegmentation-fault

Getting SIGSEGV in std::map, when using find function


I am running some small online game and there is server crash at some time. I can't find what is causing the SIGSEGV. The gdb bring me to that function:

bool Player::getStorageValue(const uint32_t key, int32_t& value) const
{
    auto it = storageMap.find(key);
    if (it == storageMap.end()) {
        value = -1;
        return false;
}

    value = it->second;
    return true;
}

Can I somehow protect it better to not let program attempt to access a restricted area of memory?

And heres my gdb log:

(gdb) bt full
#0  0x000000000054503c in std::less<unsigned int>::operator()(unsigned int const&, unsigned int const&) const ()
No symbol table info available.
#1  0x0000000000740dca 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<std::pair<unsigned int const, int> > const*, unsigned int const&) const ()
No symbol table info available.
#2  0x000000000073e145 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  0x000000000073c46f 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  0x000000000072dfa2 in Player::getStorageValue(unsigned int, int&) const ()
No symbol table info available.
#5  0x00000000006b2890 in LuaScriptInterface::luaPlayerGetStorageValue(lua_State*) ()

I've added the mutex to code to don't let threads attempt to some elements at the same time

bool Player::getStorageValue(const uint32_t key, int32_t& value) const
{
    std::lock_guard<std::mutex> lockClass(mutex_gp13);

    auto it = storageMap.find(key);
    if (it == storageMap.end()) {
        value = -1;
        return false;
    }

    value = it->second;
    return true;
}

I though that should solve my problem, but today had the same SIGSEGV with that gdb log.

Edit: I found that I didn't put mutex on function that writes to the map. Im gonna try with this now.


Solution

  • Given this is a server I'm thinking you might be multi-threading. If this is the case it could be that your map is being altered somewhere before you set the return value causing your iterator to become invalid. You then access the invalid iterator and the program dies horribly.

    If this is the case then you'll need to protect it from change with a semaphore or the like. If not then we're probably going to need a bit more information because the code looks good.