• 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!

C++ crash bug

Fortera Global

Intermediate OT User
Joined
Nov 20, 2015
Messages
1,180
Solutions
2
Reaction score
117
Hi, my server crashing all day, I got the error gdb, so if anyone can help me...

Something related to the tibia coins market

tfs 1.2 (old)

At the time of the bug tfs gets 100% use.

the line 2101 is: auto coinBalance = IOAccount::getCoinBalance(client->player->getAccount());
function:
C++:
void ProtocolGame::updateCoinBalance()
{
    NetworkMessage msg;
    msg.addByte(0xF2);
    msg.addByte(0x00);
    writeToOutputBuffer(msg);
    g_dispatcher.addTask(
            createTask(std::bind([](ProtocolGame* client) {
                if (client) {
                    auto coinBalance = IOAccount::getCoinBalance(client->player->getAccount());
                    client->player->coinBalance = coinBalance;
                    client->sendCoinBalance();
                }
            }, this))
    );
}


Crash log gdb:

Code:
#0  0x000000000057d561 in operator() (__closure=<optimized out>, client=0x1166d458) at protocolgame.cpp:2101
2101                        auto coinBalance = IOAccount::getCoinBalance(client->player->getAccount());
(gdb) bt full
#0  0x000000000057d561 in operator() (__closure=<optimized out>, client=0x1166d458) at protocolgame.cpp:2101
        coinBalance = <optimized out>
#1  __call<void, 0ul> (__args=<optimized out>, this=<optimized out>) at /usr/include/c++/4.8/functional:1296
No locals.
#2  operator()<, void> (this=<optimized out>) at /usr/include/c++/4.8/functional:1355
No locals.
#3  std::_Function_handler<void(), std::_Bind<ProtocolGame::updateCoinBalance()::__lambda3(ProtocolGame*)> >::_M_invoke(const std::_Any_data &) (
    __functor=...) at /usr/include/c++/4.8/functional:2071
No locals.
#4  0x00000000005b5d08 in operator() (this=0x140ca680) at /usr/include/c++/4.8/functional:2471
No locals.
#5  operator() (this=0x140ca670) at tasks.h:42
No locals.
#6  Dispatcher::threadMain (this=0x851ce0 <g_dispatcher>) at tasks.cpp:50
        task = 0x140ca670
        taskLockUnique = {_M_device = 0x851cf8 <g_dispatcher+24>, _M_owns = false}
#7  0x00007fe52d6a0a60 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
No symbol table info available.
#8  0x00007fe52c6d8184 in start_thread (arg=0x7fe52c6cf700) at pthread_create.c:312
        __res = <optimized out>
        pd = 0x7fe52c6cf700
        now = <optimized out>
        unwind_buf = {cancel_jmp_buf = {{jmp_buf = {140622269576960, -7867707817108392633, 0, 0, 140622269577664, 140622269576960, 7861615568647927111,
                7861615580932650311}, mask_was_saved = 0}}, priv = {pad = {0x0, 0x0, 0x0, 0x0}, data = {prev = 0x0, cleanup = 0x0, canceltype = 0}}}
        not_first_call = <optimized out>
        pagesize_m1 = <optimized out>
        sp = <optimized out>
        freesize = <optimized out>
        __PRETTY_FUNCTION__ = "start_thread"
#9  0x00007fe52ce08bed in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111
No locals.
(gdb)

whole protocolgame.cpp
protocolgame.cpp - Pastebin.com
 
Last edited by a moderator:
As I remember this is not official a code of clean tfs engine, you shouldn't use any custom made engine based of tfs 1.2 if you don't wanna expect any crashs.

If you want to use a crash-free server, you can use GitHub - otland/forgottenserver: A free and open-source MMORPG server emulator written in C++

For that I posted the whole code, if you can look and help me, I'll be grateful.


PS. I edited the code and put:

Code:
if (!client) {
                    return;
                }

But I believe that this code above has nothing to do.
 
Last edited by a moderator:
The problem should be in the method getCoinBalance
If you're using the OTX, make sure if you're with the lastest version

Code:
https://github.com/malucooo/Otxserver-New/blob/master/src/account.cpp

And, also, check your database if you changed from another OT. You should have a field for coins inside of Accounts table.

I'm not sure if the problem is it, but it doesn't costs nothing to check :p
 
The problem should be in the method getCoinBalance
If you're using the OTX, make sure if you're with the lastest version

Code:
https://github.com/malucooo/Otxserver-New/blob/master/src/account.cpp

And, also, check your database if you changed from another OT. You should have a field for coins inside of Accounts table.

I'm not sure if the problem is it, but it doesn't costs nothing to check :p

I'm not using otx, it's different, but thanks for the answer
 
Update: I'm trying to swap my code but got error on compilation:

ACYZzEnFS06PkMdawtAkHg.png


C++:
void ProtocolGame::sendCoinBalance()
{
    Database& db = Database::getInstance();

    std::ostringstream query;

    query << "SELECT `premium_points` FROM `accounts` WHERE `id`=" + std::to_string(player->getAccount());
    DBResult_ptr result = db.storeQuery(query.str());
    if (!result) {
        return;
    }

    NetworkMessage msg;
    msg.addByte(0xF2);
    msg.addByte(0x01);

    msg.addByte(0xDF);
    msg.addByte(0x01);

    msg.add<uint32_t>(result->getNumber<uint32_t>("premium_points")); //total coins
    msg.add<uint32_t>(result->getNumber<uint32_t>("premium_points")); //transferable coins

    writeToOutputBuffer(msg);
}
 
Update: I'm trying to swap my code but got error on compilation:

ACYZzEnFS06PkMdawtAkHg.png


C++:
void ProtocolGame::sendCoinBalance()
{
    Database& db = Database::getInstance();

    std::ostringstream query;

    query << "SELECT `premium_points` FROM `accounts` WHERE `id`=" + std::to_string(player->getAccount());
    DBResult_ptr result = db.storeQuery(query.str());
    if (!result) {
        return;
    }

    NetworkMessage msg;
    msg.addByte(0xF2);
    msg.addByte(0x01);

    msg.addByte(0xDF);
    msg.addByte(0x01);

    msg.add<uint32_t>(result->getNumber<uint32_t>("premium_points")); //total coins
    msg.add<uint32_t>(result->getNumber<uint32_t>("premium_points")); //transferable coins

    writeToOutputBuffer(msg);
}

C++:
Database* db = Database::getInstance();
 
But is there a difference in the function I'm changing for mine? Or is it both the same? I think this may not fix the bug, what do you think?
yes there's a difference between yours and the one you're updating it with.
look up ProtocolGame::sendCoinBalance() and compare it with the new one, they're different.
 
For that I posted the whole code, if you can look and help me, I'll be grateful.


PS. I edited the code and put:

Code:
if (!client) {
                    return;
                }

But I believe that this code above has nothing to do.
client is already checked in original code. If you want to use such check, add it on player ptr which isnt checked at all if(client and client->player) { execute code }

Run server on debug mode, then gdb will tell you exact values on variables which failed
 
Back
Top