CleverRaven / Cataclysm-DDA

Cataclysm - Dark Days Ahead. A turn-based survival game set in a post-apocalyptic world.
http://cataclysmdda.org
Other
10.62k stars 4.17k forks source link

Segmentation fault triggered by bandit attacks #75707

Closed x-qq closed 2 months ago

x-qq commented 2 months ago

Describe the bug

Currently whenever there are bandits participating in any sort of combat, there is a significant probability of a segfault happening.

The program has crashed.
See the log file for a stack trace.
CRASH LOG FILE: ./config/crash.log
VERSION: cdda-experimental-2024-08-03-0533 1c140ab
TYPE: Signal
MESSAGE: SIGSEGV: Segmentation fault
STACK TRACE:

    0x564,fad,ffc,8cf    src/debug.cpp:967    bt_full
    0x564,fad,ffc,8cf    src/debug.cpp:1,232    debug_write_backtrace(std::ostream&)
    0x564,fad,fd3,ada    src/crash.cpp:89    log_crash
    0x564,fad,fd3,e27    src/crash.cpp:146    signal_handler
    0x7f6,dcb,858,57f    ./signal/../sysdeps/unix/sysv/linux/x86_64/libc_sigaction.c:0    [unknown func]
    0x564,fae,75a,988    src/npcmove.cpp:2,723    npc::wont_hit_friend(tripoint const&, item const&, bool) const
    0x564,fae,748,a26    src/npc_attack.cpp:638    npc_attack_throw::use(npc&, tripoint const&) const
    0x564,fae,76e,52e    src/npcmove.cpp:1,582    npc::execute_action(npc_action)
    0x564,fae,770,9c0    src/npcmove.cpp:1,560    npc::move()
    0x564,fae,061,aeb    src/do_turn.cpp:359    monmove
    0x564,fae,061,aeb    src/do_turn.cpp:657    do_turn()
    0x564,fad,b4b,a2c    src/main.cpp:873    main
    0x7f6,dcb,842,c89    ../sysdeps/nptl/libc_start_call_main.h:58    __libc_start_call_main
    0x7f6,dcb,842,d44    ../csu/libc-start.c:360    __libc_start_main_impl
    0x564,fad,cb9,f8d    [unknown src]:0    [unknown func]
    0xf,fff,fff,fff,fff,fff    [unknown src]:0    [unknown func]
Aborted

Attach save file

Debug-trimmed.tar.gz

Steps to reproduce

  1. Load the provided save
  2. Using debug menu, spawn 10-15 somewhat armored zombies (like zombie cop) in various spots inside the bandit camp north.
  3. Watch the fight and get a segfault with a high probability. In my observation it segfaults 8 times out of 10.

Expected behavior

No segfaults.

Screenshots

bug1

bug2

Versions and configuration

Game version: cdda-linux-tiles-x64-2024-08-03-0533, unmodified

Additional context

No response

l29ah commented 2 months ago

/confirmed Detailed backtrace and repro: https://github.com/CleverRaven/Cataclysm-DDA/issues/75331#issuecomment-2276780966

PatrikLundell commented 2 months ago

It crashes in npcmove.cpp operation npc::wont_hit_friend at the creation and assignment of "dispersion" because it.ammo_data() returns a null pointer. As in the referenced report, "it" is a crossbow, and it appears item::ammo_data returns a null pointer (that's what the debugger says, and sometimes it doesn't lie).

The code would have to account for this possibility in some way, as that's a legal return value for the ammo_data operation. I don't know why ammo_data would be missing, and thus what conditions to account for (out of ammo?, something else?). If it's out of ammo you'd want to switch to another weapon rather than waiving an empty one around, but for some other cases you might want to use a default value.

I think this is something for someone who known how the ranged weapon stuff is supposed to work.

osuphobia commented 2 months ago

Seems to be caused by https://github.com/CleverRaven/Cataclysm-DDA/pull/75297

RenechCDDA commented 2 months ago

This looks to be the issue fixed by #75418. Your experimental version is two weeks out of date, please try upgrading and seeing if the issue persists.

PatrikLundell commented 2 months ago

No, it's unfortunately not due to an old version. Here's the version I used.

Also, the error is in a different place of the code compared to #75418.

x-qq commented 2 months ago

I have tested with cdda-linux-tiles-x64-2024-08-15-1712 and it's no longer segfaulting (3 out of 3).

osuphobia commented 2 months ago

Still crashing when a bandit firing a crossbow.

diff --git a/src/npcmove.cpp b/src/npcmove.cpp
index a1ac030171..8b1ca0816c 100644
--- a/src/npcmove.cpp
+++ b/src/npcmove.cpp
@@ -2712,6 +2712,11 @@ int npc::confident_throw_range( const item &thrown, Creature *target ) const
 // Index defaults to -1, i.e., wielded weapon
 bool npc::wont_hit_friend( const tripoint &tar, const item &it, bool throwing ) const
 {
+    if( it.is_gun() && it.empty() ) {
+        return true;
+    }
+
     if( throwing && rl_dist( pos(), tar ) == 1 ) {
         return true;    // If we're *really* sure that our aim is dead-on
     }

Fixed with the code above.