Game segfaults if the server errors before it can reach a NetVars hook
This is an extremely bizarre bug that triggers a crash on clients if a server somehow triggers a Lua error before a NetVars hook has been registered, and clients can register the hook successfully. What's weird about it is that it's incredibly sensitive to context, and seems to only trigger if:
- A NetVars hook is already registered prior to the failed registered hook in question.
- At least one unique variable is synchronized in each NetVars hook.
- At least one variable that is synchronized is a table (this might not be a criteria, though, but this behaves so erratically that it's hard to verify).
A minimal reproducible example script to illustrate:
local value = nil
local extra = { "a", "b", "c" }
addHook("NetVars", function (network)
extra = network(extra)
end)
if isserver then
error("o no")
end
addHook("NetVars", function (network)
value = network(value)
end)
Save this in a Lua file, start a dedicated server with this script loaded and then join the server. The error that triggers is:
ERROR: A nil key in table 1 was found! (Invalid key type or corrupted save?)
Followed by a segfault with the following info from GDB:
Thread 23.1 "lsdl2srb2.debug" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff529d640 (LWP 14959)]
mainposition (t=t@entry=0x300, key=key@entry=0x7fffdc01ed60) at blua/ltable.c:111
111 return hashpointer(t, gcvalue(key));
(gdb) bt
#0 mainposition (t=t@entry=0x300, key=key@entry=0x7fffdc01ed60) at blua/ltable.c:111
#1 0x00005555557aa673 in luaH_get (t=t@entry=0x300, key=key@entry=0x7fffdc01ed60) at blua/ltable.c:483
#2 0x00005555557aaa33 in luaH_set (L=L@entry=0x55555b5f09a0, t=0x300, key=key@entry=0x7fffdc01ed60)
at blua/ltable.c:496
#3 0x0000555555799c33 in lua_rawset (L=0x55555b5f09a0, idx=idx@entry=-3) at blua/lapi.c:666
#4 0x000055555576d61c in UnArchiveTables () at lua_script.c:1618
#5 0x000055555576ddd1 in LUA_UnArchive () at lua_script.c:1709
#6 0x00005555556e7e3c in P_LoadNetGame (reloading=reloading@entry=false) at p_saveg.c:4565
#7 0x000055555560129d in CL_LoadReceivedSavegame (reloading=reloading@entry=false) at d_clisrv.c:1708
#8 0x0000555555608041 in CL_ServerConnectionTicker
(tmpsave=tmpsave@entry=0x7fffffffe0f0 "/home/gustaf/.srb2/$$$.sav", oldtic=oldtic@entry=0x7fffffffe1fc, asksent=asksent@entry=0x7fffffffe1f8) at d_clisrv.c:2411
#9 0x0000555555608333 in CL_ConnectToServer () at d_clisrv.c:2588
#10 0x000055555560857d in Command_connect () at d_clisrv.c:2846
#11 0x000055555564a737 in COM_ExecuteString (ptext=ptext@entry=0x7fffffffe270 "\033") at command.c:650
#12 0x000055555564a8a6 in COM_BufExecute () at command.c:261
#13 0x000055555564b207 in COM_BufTicker () at command.c:211
#14 0x0000555555608c4f in TryRunTics (realtics=<optimized out>, realtics@entry=4) at d_clisrv.c:5306
#15 0x00005555555fec04 in D_SRB2Loop () at d_main.c:811
#16 0x00005555555d7716 in main (argc=<optimized out>, argv=<optimized out>) at sdl/i_main.c:258