• 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+ CreatureEvent crashing in Linux (working fine in windows)

jakub742

Active Member
Joined
May 1, 2010
Messages
199
Solutions
3
Reaction score
42
Location
Slovakia
Hi, i just found out that my server is crashing on "PrepareDeath" CreatureEvent, but only on Linux.

my script:
LUA:
local prepareDeath = CreatureEvent('PrepareDeath')
prepareDeath:type('preparedeath')

function prepareDeath.onPrepareDeath(player)
    player:getPosition():sendMagicEffect(CONST_ME_TELEPORT)
    player:teleportTo(player:getTown():getTemplePosition())
    return false
end

prepareDeath:register()

On Windows player is successfully teleported to temple. On Linux will get segmentation fault. However if i comment
Code:
player:teleportTo(player:getTown():getTemplePosition())
this line its working even on Linux, player has 1 health and is unable to die. Also sendMagicEffect works fine.
With player:teleportTo it will crash on linux.

Also crashing with setHealth addMana etc.

Pretty weird. Does anyone knows why ? :D
TFS 1.5 Nekiro's downgrade 772

gdb backtrace
 
Last edited:
can you try find all onPrepareDeath scripts and check what they doing and if can disable all other then this script, probably order of events is different on windows and linux and this "fix" issue on windows
 
can you try find all onPrepareDeath scripts and check what they doing and if can disable all other then this script, probably order of events is different on windows and linux and this "fix" issue on windows
There is no difference. Same data folder same sources and this is the only onPrepareDeath script. And its working with return false without player dying, problem is when i use teleportTo or setHealth. It throws segmentation fault under linux and working fine on windows with teleporting player.
 
LUA:
local prepareDeath = CreatureEvent('PrepareDeath')
prepareDeath:type('preparedeath')
local tpPosition = Position(56, 265, 7)

function prepareDeath.onPrepareDeath(player)
    player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) -- this is working
    player:setHealth(player:getMaxHealth())                 -- this is working
    player:teleportTo(tpPosition)                           -- this will crash the server under linux, tested code in talkactions and its working
    return false
end

prepareDeath:register()
Post automatically merged:

can you share backtrace from linux crash?
gdb backtrace

What is weird is that in gdb i can see this on the top:

LUA:
2506       /usr/src/forgottenserver/src/protocolgame.cpp: No such file or directory.

line 2506 in protocolgame.cpp is start of "sendRemoveTileCreature"

1728634071382.webp
 
Last edited:
I found a workaround but would like to know why its crashing under linux when teleporting inside onPrepareDeath()

If i do this
LUA:
function prepareDeath.onPrepareDeath(creature, killer)
    if creature:isPlayer() then
        creature:registerEvent('healthChange')
    end
end

that i register new event for healthChange inside onPrepareDeath and then its working from onHealthChange -> I can then teleport player from onHealthChange. :D

LUA:
function event.onHealthChange(creature)
    if creature:isPlayer() then
        creature:teleportTo(tpPosition)
        creature:unregisterEvent('healthChange')
        return false
    end
    return true
end
 
Bump. Still not resolved, update:

LUA:
local tpPosition = Position(56, 265, 7)
local prepareDeath = CreatureEvent('PVP_prepareDeath')
prepareDeath.type('preparedeath')

function prepareDeath.onPrepareDeath(creature, killer)
    if creature:isPlayer() then
        if creature:isPlayer() then
            local tile = Tile(creature:getPosition())
            if not tile or not tile:hasFlag(TILESTATE_PVPZONE) then
                return true
            end
            creature:setHealth(creature:getMaxHealth())
            creature:addMana(creature:getMaxMana())
            creature:teleportTo(tpPosition, false)

            return false
        end
    end
    return true
end

prepareDeath:register()

In windows working fine, under linux segmentation fault when creature:teleportTo(tpPosition, false) inside onPrepareDeath event.
Same behaviour on clean nekiro's 772 downgrade.
Something with Protocolgame.cpp
Code:
sendRemoveTileCreature
Line 2500 when sendRemoveTileCreature method starts.

Code:
0x00005613b44c4aff in ProtocolGame::sendRemoveTileCreature (this=0x0, creature=0x0, pos=..., stackpos=0) at /usr/src/forgottenserver/src/protocolgame.cpp:2500
"Program received signal: SIGSEGV
Working with
Code:
creature:teleportTo(creature:getPosition(), false)
because its not changing position.

I added logging in sendRemoveTileCreature

C++:
void ProtocolGame::sendRemoveTileCreature(const Creature* creature, const Position& pos, uint32_t stackpos)
{
    if (this == nullptr || creature == nullptr) { //this was offered by open ai chat but no help
        std::cerr << "Error: this or creature is nullptr in sendRemoveTileCreature" << std::endl;
        return;
    }
    // Log the parameter values
    std::cerr << "ProtocolGame::sendRemoveTileCreature called with parameters:" << std::endl;
    std::cerr << "  creature: " << creature << std::endl;
    if (creature) {
        std::cerr << "  creature ID: " << creature->getID() << std::endl;
    }
    std::cerr << "  position: (" << pos.x << ", " << pos.y << ", " << pos.z << ")" << std::endl;
    std::cerr << "  stackpos: " << stackpos << std::endl;


    if (creature == nullptr) {
        std::cerr << "Error: creature is nullptr" << std::endl;
        return;
    }

    if (stackpos < 10) {
        if (!canSee(pos)) {
            std::cerr << "  Cannot see position, returning." << std::endl;
            return;
        }

        NetworkMessage msg;
        RemoveTileThing(msg, pos, stackpos);
        writeToOutputBuffer(msg);
        return;
    }

    NetworkMessage msg;
    msg.addByte(0x6C);
    msg.add<uint16_t>(0xFFFF);
    msg.add<uint32_t>(creature->getID());
    writeToOutputBuffer(msg);
}

RemoveTileThing
C++:
void ProtocolGame::RemoveTileThing(NetworkMessage& msg, const Position& pos, uint32_t stackpos)
{
    // Log the parameter values
    std::cerr << "ProtocolGame::RemoveTileThing called with parameters:" << std::endl;
    std::cerr << "  position: (" << pos.x << ", " << pos.y << ", " << pos.z << ")" << std::endl;
    std::cerr << "  stackpos: " << stackpos << std::endl;

    if (stackpos >= 10) {
        std::cerr << "  stackpos is greater than or equal to 10, returning." << std::endl;
        return;
    }

    msg.addByte(0x6C);
    msg.addPosition(pos);
    msg.addByte(stackpos);

    // Log the completion of the method
    std::cerr << "  RemoveTileThing completed successfully." << std::endl;
}


Outputs when onPrepareDeath is triggered same players same positions.
Windows:
Code:
ProtocolGame::sendRemoveTileCreature called with parameters:
  creature: 000001D14E45E050
  creature ID: 268435456
  position: (49, 265, )
  stackpos: 2
ProtocolGame::RemoveTileThing called with parameters:
  position: (49, 265, )
  stackpos: 2
  RemoveTileThing completed successfully.
ProtocolGame::sendRemoveTileCreature called with parameters:
  creature: 000001D14E45E050
  creature ID: 268435456
  position: (49, 265, )
  stackpos: 2
  Cannot see position, returning.
ProtocolGame::sendRemoveTileCreature called with parameters:
  creature: 000001D14E45E050
  creature ID: 268435456
  position: (37, 262, )
  stackpos: 2
ProtocolGame::RemoveTileThing called with parameters:
  position: (37, 262, )
  stackpos: 2
  RemoveTileThing completed successfully.
ProtocolGame::sendRemoveTileCreature called with parameters:
  creature: 000001D14E45E050
  creature ID: 268435456
  position: (37, 262, )
  stackpos: 2
  Cannot see position, returning.

Linux:
Code:
ProtocolGame::sendRemoveTileCreature called with parameters:
  creature: 0x7f93811e1060
  creature ID: 268435458
  position: (49, 265, )
  stackpos: 2
ProtocolGame::RemoveTileThing called with parameters:
  position: (49, 265, )
  stackpos: 2
  RemoveTileThing completed successfully.
ProtocolGame::sendRemoveTileCreature called with parameters:
  creature: 0x7f93811e1060
  creature ID: 268435458
  position: (49, 265, )
  stackpos: 2
  Cannot see position, returning.

2500       /usr/src/forgottenserver/src/protocolgame.cpp: No such file or directory.
Thread 2 "tfs" received signal SIGSEGV, Segmentation fault.
[Switching to LWP 18]
0x000055569e387b1e in ProtocolGame::sendRemoveTileCreature (this=0x0, creature=0x0, pos=..., stackpos=0) at /usr/src/forgottenserver/src/protocolgame.cpp:2500
"Program received signal: SIGSEGV
 

Attachments

Back
Top