Novum / vkQuake

Vulkan Quake port based on QuakeSpasm
GNU General Public License v2.0
1.8k stars 220 forks source link

Assertion failure in edict allocator on E1M3 #726

Closed kotauskas closed 3 weeks ago

kotauskas commented 3 weeks ago

Describe the bug vkQuake aborts with the following assertion failure:

vkquake: ../Quake/pr_edict.c:74: ED_Alloc: Assertion `e->next_free == NULL' failed.

To Reproduce I can consistently trigger this crash on E1M3 on hard difficulty by loading into the save file provided below, rushing into the first corridor and flinging a grenade at the zombies as shown in the screenshot below. The crash occurs before the grenade projectile can be seen or heard.

Note that shooting slightly off from the direction shown in the screenshot does not trigger the crash.

Expected behavior Lack of crashes.

Screenshots The frame that directly precedes the crash: Freeze frame

Desktop:

Output of vulkaninfo

Mod Official single-player campaign, E1M3: The Necropolis.

Additional context The vkQuake version is as follows:

Command line: vkquake
Found SDL version 2.30.6
Detected 12 CPUs.
Initializing vkQuake 1.31.1
Built with GCC 14.2.1

It was built with the AUR PKGBUILD with the following flags:

CFLAGS="-march=native -O3 -pipe -fno-plt -fexceptions \
        -Wp,-D_FORTIFY_SOURCE=3 -Wformat -Werror=format-security \
        -fstack-clash-protection -fcf-protection \
        -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer"
LDFLAGS="-Wl,-O1 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now \
         -Wl,-z,pack-relative-relocs -fuse-ld=mold"
Configuration ```glsl unbindall bind "TAB" "+showscores" bind "SPACE" "+jump" bind "'" "f3 ' save" bind "1" "impulse 2" bind "2" "impulse 3" bind "3" "impulse 4" bind "4" "impulse 5" bind "\" "impulse 1" bind "`" "toggleconsole" bind "a" "+moveleft" bind "d" "+moveright" bind "f" "impulse 7" bind "r" "impulse 6" bind "s" "+back" bind "v" "impulse 8" bind "w" "+forward" bind "ALT" "+zoom" bind "CTRL" "+movedown" bind "SHIFT" "+speed" bind "F5" "save quick" bind "F9" "load quick" bind "MOUSE1" "+attack" _cl_color "0" _cl_name "player" _snd_mixahead "0.1" autofastload "1" autoload "1" bgm_extmusic "1" bgmvolume "0.5" cfg_unbindall "1" cl_alwaysrun "1" cl_backspeed "200" cl_bob "0.02" cl_forwardspeed "200" cl_gun_fovscale "1" cl_maxpitch "90" cl_minpitch "-90" cl_rollangle "2.0" cl_startdemos "1" contrast "1.4" crosshair "2" external_ents "1" external_vis "1" fov "120" fov_adapt "1" gamma "0.9" gl_farclip "16384" gl_fullbrights "1" gl_lodbias "0" gl_zfix "1" host_maxfps "60" joy_deadzone_look "0.175" joy_deadzone_move "0.175" joy_deadzone_trigger "0.2" joy_enable "1" joy_exponent "2" joy_exponent_move "2" joy_invert "0" joy_outer_threshold_look "0.02" joy_outer_threshold_move "0.02" joy_sensitivity_pitch "130" joy_sensitivity_yaw "240" joy_swapmovelook "0" m_forward "1" m_pitch "0.022" m_side "0.8" m_yaw "0.022" r_alphasort "1" r_clearcolor "2" r_dynamic "1" r_fastclear "1" r_fteparticles "1" r_lerplightstyles "1" r_lerpmodels "1" r_lerpmove "1" r_lerpturn "1" r_loadmd5models "1" r_lodbias "1" r_md5models "1" r_novis "0" r_particles "2" r_quadparticles "1" r_rtshadows "1" r_scale "0" r_simd "1" r_usesops "1" r_viewmodel_quake "0" r_wateralpha "1" r_waterwarp "1" r_waterwarpcompute "1" saved1 "0" saved2 "0" saved3 "0" saved4 "0" savedgamecfg "0" scr_autoclock "1" scr_conalpha "0.5" scr_conanim "0" scr_conspeed "500" scr_conwidth "0" scr_relativescale "2" scr_relconscale "1" scr_relcrosshairscale "1" scr_relmenuscale "1" scr_relsbarscale "1" scr_sbaralpha "0.75" scr_showfps "0" scr_style "0" sensitivity "3.5" snd_pauselooping "1" snd_waterfx "1" sv_altnoclip "1" sv_gameplayfix_elevators "2" v_autopitch "0" v_gunkick "2" vid_anisotropic "1" vid_borderless "0" vid_desktopfullscreen "0" vid_filter "1" vid_fsaa "8" vid_fsaamode "0" vid_fullscreen "1" vid_height "1080" vid_palettize "1" vid_refreshrate "60" vid_vsync "1" vid_width "1920" viewsize "100" viewsize_allow_shrinking "0" volume "0.3" zoom_fov "30" zoom_speed "8" vid_restart +mlook ```

Save file (in .zip)

kotauskas commented 3 weeks ago

Can still reproduce after recompiling with -O2 instead of -O3.

j4reporting commented 3 weeks ago

I can't reproduce this atm with the savefile.

  1. Could you please include the output of the command viewpos at the spot that triggers the assert?
  2. Does this also happen if you start/restart the map with command map e1m3?
  3. Does the appimage from github also trigger this assert?
kotauskas commented 3 weeks ago

Via bind MOUSE1 "viewpos; +attack", I got Viewpos: (-265 -1776 148) -19 76 0 in terminal output on a mouse click that crashed the game. The crash clearly occurs on the frame on which +attack comes through, since the log in the top left corner does not display the viewpos readout on the final frame.

Here's the corresponding core dump (decompresses to 1.3 GiB).

I haven't been able to reproduce this with the AppImage or via map e1m3, although the bug now appears to be less consistent than it was before, so I'm not sure if it's because it doesn't happen in those cases or if I'm just not hitting a unit-perfect or frame-perfect sequence. The AppImage also displays a cursor in the middle of the screen, which may warrant a separate bug report, since I didn't need to do anything special to get it to hide in the AUR build.

vsonnier commented 3 weeks ago

Cant reproduce either on master with either original or Remaster id1. However, there are console errors when loading the savefile in both configurations 'xxxx' is not a global. Indeed at the begining of the save file there is the following:

"VEC_ORIGIN_x" "0.000000"
"VEC_ORIGIN_y" "0.000000"
"VEC_ORIGIN_z" "0.000000"
"VEC_HULL_MIN_x" "-16.000000"
"VEC_HULL_MIN_y" "-16.000000"
"VEC_HULL_MIN_z" "-24.000000"
"VEC_HULL_MAX_x" "16.000000"
"VEC_HULL_MAX_y" "16.000000"
"VEC_HULL_MAX_z" "32.000000"
"VEC_HULL2_MIN_x" "-32.000000"
"VEC_HULL2_MIN_y" "-32.000000"
"VEC_HULL2_MIN_z" "-24.000000"
"VEC_HULL2_MAX_x" "32.000000"
"VEC_HULL2_MAX_y" "32.000000"
"VEC_HULL2_MAX_z" "64.000000"

which disappear when we save again. Is the original save from running KEX, or Ironwail, or anything not vkQuake ?

Anyway, I intended to get rid of that linked-list for free edicts and replace it with something much simpler (a FIFO), so that is the occasion.

j4reporting commented 3 weeks ago

the mouse cursor is a know issue with the appimage and has been fixed in SDL2.

kotauskas commented 3 weeks ago

The save file is definitely from vkQuake (the initial -O3 build I encountered the bug on), no other source ports have been installed on the system. Those VEC_* lines were saved by vkQuake itself.

j4reporting commented 3 weeks ago

viewpos `(-265 -1776 148) -19 76 0
so it's a +jump followed by +attack near the top ? still can't reproduce, though.

you'll find the VEC_* lines with the same values in all quake savegames.

kotauskas commented 3 weeks ago

Yes, I almost always jump in this spot. Not sure if the bug can happen without the jump, but it definitely doesn't happen if I shoot any later. (I worked around this by not being as aggressive in the first few seconds and the game hasn't crashed in any other location since.)

vsonnier commented 3 weeks ago

Those VEC* lines were saved by vkQuake itself. you'll find the VEC* lines with the same values in all quake savegames.

Nope, none of my saves have those and Ironwail complains the same way vkQuake reading them. (Win10)

j4reporting commented 3 weeks ago

interesting.. new written save file vkquake 1.31.1 on win10 using the binary from github :)

"VEC_ORIGIN_x" "0.000000"
"VEC_ORIGIN_y" "0.000000"
"VEC_ORIGIN_z" "0.000000"
"VEC_HULL_MIN_x" "-16.000000"
"VEC_HULL_MIN_y" "-16.000000"
"VEC_HULL_MIN_z" "-24.000000"
"VEC_HULL_MAX_x" "16.000000"
"VEC_HULL_MAX_y" "16.000000"
"VEC_HULL_MAX_z" "32.000000"
"VEC_HULL2_MIN_x" "-32.000000"
"VEC_HULL2_MIN_y" "-32.000000"
"VEC_HULL2_MIN_z" "-24.000000"
"VEC_HULL2_MAX_x" "32.000000"
"VEC_HULL2_MAX_y" "32.000000"
"VEC_HULL2_MAX_z" "64.000000"
vsonnier commented 3 weeks ago

Ah now I understand : this is the case if you use only the original PAK0.pak + PAK1.pak . My usual setup add other fixes .pak from https://github.com/NightFright2k19 (progs.dat, models, water vis, new colored lighmaps...etc)

This particular assert happens when we exactly take the last free edict... this is a very trensient situation depending on the dynamic of the game...

The best 'fix' is probably to get rid of the linked-list entirely. I pushed a commit on master for that just now.

kotauskas commented 3 weeks ago

Sweet, great work triaging and patching this one so quickly!

vsonnier commented 3 weeks ago

Technically, it is rather a change in implementation instead of a real fix. But well, the assert is gone :)