EvEmu-Project / evemu_Crucible

Emulator for EvE Online's Crucible expansion
https://evemu.dev
174 stars 68 forks source link

segfault on board when you're surrounded by hostile ships #212

Open NukedBart opened 2 years ago

NukedBart commented 2 years ago

Describe the bug as the title

To Reproduce Steps to reproduce the behavior:

  1. board ibis in station
  2. undock
  3. issue .spawn 23333 100
  4. get destoryed
  5. issue .spawn 601
  6. board the new ship
  7. segfault, client crash

Expected behavior board the ship and get destroyed again

System Details (please complete the following information):

jdhirst commented 2 years ago

@NukedBart can you please provide the backtrace for the segfault?

NukedBart commented 2 years ago

will do that soon

NukedBart commented 2 years ago

0x000055a553f24ca0 in ModuleManager::GetRandModule (this=0x55a55e3cf130)
    at /evemubuild/evemu_Crucible/src/eve-server/ship/modules/ModuleManager.cpp:318
318         return modVec[MakeRandomInt(0, modVec.size())];
(gdb) bt
#0  0x000055a553f24ca0 in ModuleManager::GetRandModule (this=0x55a55e3cf130)
    at /evemubuild/evemu_Crucible/src/eve-server/ship/modules/ModuleManager.cpp:318
#1  0x000055a553f273b8 in ModuleManager::DamageRandModule (this=0x55a55e3cf130)
    at /evemubuild/evemu_Crucible/src/eve-server/ship/modules/ModuleManager.cpp:769
#2  0x000055a553ef6b95 in ShipItem::DamageRandModule (this=0x55a561073490)
    at /evemubuild/evemu_Crucible/src/eve-server/ship/Ship.h:167
#3  0x000055a553ef2506 in ShipSE::DamageRandModule (this=0x55a560b9a1c0, chance=0.100000001)
    at /evemubuild/evemu_Crucible/src/eve-server/ship/Ship.cpp:2501
#4  0x000055a553fb36d2 in SystemEntity::ApplyDamage (this=0x55a560b9a1c0, d=...)
    at /evemubuild/evemu_Crucible/src/eve-server/system/Damage.cpp:283
#5  0x000055a553ee2013 in Missile::HitTarget (this=0x55a56116fb80)
    at /evemubuild/evemu_Crucible/src/eve-server/ship/Missile.cpp:275
#6  0x000055a553ee119c in Missile::Process (this=0x55a56116fb80)
    at /evemubuild/evemu_Crucible/src/eve-server/ship/Missile.cpp:165
#7  0x000055a553ff689c in SystemManager::ProcessTic (this=0x55a556498f50)
    at /evemubuild/evemu_Crucible/src/eve-server/system/SystemManager.cpp:240
#8  0x000055a553b03bba in EntityList::Process (this=0x55a55572d350)
    at /evemubuild/evemu_Crucible/src/eve-server/EntityList.cpp:240
#9  0x000055a553ac741c in main (argc=1, argv=0x7ffc42a3a3b8) at /evemubuild/evemu_Crucible/src/eve-server/eve-server.cpp:900```
backtrace
----------------------------------------------------------------------------------
```21:44:12 Y Command_spawn: Bart Nuked: Spawned 601 in space, 1 times
21:44:13 [Service] config::GetMultiOwnersEx()
21:44:17 [Service] ship::MachoResolveObject()
21:44:17 [Service] ship::MachoBindObject()
21:44:17 [ClientSessionDump] Sending Session packet:
21:44:17 [ClientSessionDump] Packet:
21:44:17 [ClientSessionDump]   Type: macho.SessionChangeNotification
21:44:17 [ClientSessionDump]   Command: SESSIONCHANGENOTIFICATION (16)
21:44:17 [ClientSessionDump]   Source:
21:44:17 [ClientSessionDump]     Node: nodeID=888444 service='' callID=0
21:44:17 [ClientSessionDump]   Dest:
21:44:17 [ClientSessionDump]     Client: clientID=0 callID=0 service=''
21:44:17 [ClientSessionDump]   User ID: 1
21:44:17 [ClientSessionDump]   Payload:
21:44:17 [ClientSessionDump]  Tuple: 3 elements
21:44:17 [ClientSessionDump]   [ 0]       Long: 0
21:44:17 [ClientSessionDump]   [ 1]  Tuple: 2 elements
21:44:17 [ClientSessionDump]   [ 1]   [ 0]    Integer: 0
21:44:17 [ClientSessionDump]   [ 1]   [ 1]  Dictionary: 1 entries
21:44:17 [ClientSessionDump]   [ 1]   [ 1]   [ 0]   Key:     String: 'shipid'
21:44:17 [ClientSessionDump]   [ 1]   [ 1]   [ 0] Value:  Tuple: 2 elements
21:44:17 [ClientSessionDump]   [ 1]   [ 1]   [ 0] Value:   [ 0]    Integer: 140000022
21:44:17 [ClientSessionDump]   [ 1]   [ 1]   [ 0] Value:   [ 1]    Integer: 140000074
21:44:17 [ClientSessionDump]   [ 2]   List: 2 elements
21:44:17 [ClientSessionDump]   [ 2]   [ 0]    Integer: -1
21:44:17 [ClientSessionDump]   [ 2]   [ 1]    Integer: 888444
21:44:17 [ClientSessionDump]   Named Payload: None (null)
21:44:17 [Service] dogmaIM::MachoBindObject()
21:44:17 [Service] config::GetDynamicCelestials()
Segmentation fault (core dumped)```
output
jdhirst commented 2 years ago

@NukedBart

Hmm, I wonder why GetRandModule is segfaulting like this.

I tried to reproduce it here without success: https://youtu.be/9VNCp6NjofQ

I used these commands: image

Its possible this is a race condition? How was your CPU utilisation at the time?

This is all GetRandModule does:

GenericModule* ModuleManager::GetRandModule()
{
    std::vector<GenericModule*> modVec;
    for (uint8 flag = flagLowSlot0; flag < flagFixedSlot; ++flag)
        if (m_modules[flag] != nullptr)
            modVec.push_back(m_modules[flag]);

    if (modVec.empty () == true)
        return nullptr;

    return modVec[MakeRandomInt(0, modVec.size())];
}

@Almamu any thoughts?

P.S. I also noticed that mobs don't pod-kill you. This is not correct behavior, I believe they should be doing this, but maybe there is a check for that in place?

jdhirst commented 2 years ago

@NukedBart Is there anything else in the reproduction of this issue which I did not do during my test?

Are you able to replicate this with a completely fresh Docker install using a blank db? (the reason I request this is that it will rule out many other possible causes of such a problem)

Also, which specific commit version of EVEmu is being used here?

Almamu commented 2 years ago

Its possible this is a race condition? How was your CPU utilisation at the time?

Shouldn't EVEmu be single threaded for all intents and purposes? I don't remember off the top of my head if there's any actual threading interacting with items. Looking at the offending code doesn't look like it's accessing anything that could be modified at the same time (otherwise It would have segfaulted somewhere else, and not on the return imo).

@jdhirst

My only guess is that MakeRandomInt is returning a range of [0-x], instead of [0-x) (at least that's what I'd expect it to return) which would explain the crash, and I've actually managed to reproduce it in a simple test program, so most likely that's the situation here:

#include <iostream>
#include <vector>
#include <cstdint>

double MakeRandomFloat (double low, double high);

int64_t MakeRandomInt (int64_t low, int64_t high)
{
    return (int64_t) MakeRandomFloat ((double)low, (double)high);
}

double MakeRandomFloat (double low, double high)
{
    if( low == high )
        return low;

    static bool seeded = false;
    if( !seeded )
    {
        time_t x = ::time( NULL );
        ::srand( x * ( x % (time_t)( high - low ) ) );
        seeded = true;
    }

    return low + ( high - low ) * ::rand() / RAND_MAX;
}

int main()
{
    std::vector<int> values;

    values.push_back (5);
    values.push_back (10);

    std::cout << "Testing for size " << values.size() << std::endl;

    for (int i = 0; i < 100000; i ++)
    {
        if (MakeRandomInt (0, values.size()) == values.size())
            std::cout << "CRASHING WAITING TO HAPPEN!" << std::endl;
    }

    return 0;
}

This one might require some extra thought tho, mainly because depending on the situation we might want MakeRandomInt to return [0-x] instead of [0-x).