What happened?
FXServer's svMain thread enters an infinite loop at 100% CPU, repeatedly throwing std::bad_any_cast, and never recovers. txAdmin kills the server after ~60s of missed heartbeats (Loop svMain seems hung!, watchdog stack: root). We captured 10+ occurrences over 6 days on a ~250-slot production server, at player counts from 4 to 199, at random times.
gdb on the live spinning process (breakpoint on __cxa_throw, fires repeatedly):
exception type: St12bad_any_cast
#0 libstdc++.so.6.0.33+0xc5ad0 (__cxa_throw)
#1 libcitizen-server-impl.so+0x3aebbc
#2 libcitizen-server-impl.so+0x3ae1fd
#3 fx::invoker::ScriptNativeContext::Invoke() (libcitizen-scripting-core.so+0xda52e)
#4+ ~40 frames of libcitizen-scripting-lua.so (Lua VM)
A raw dump of the svMain stack during the spin contains the string literal "playerEntity". A full-heap scan finds no repeated Lua error strings — the exception never reaches script level; the engine re-throws forever.
This is not script load: resmon/profiler captures on the same days show a healthy server — total script time ~6–10% of svMain at 250 players, no resource above normal, no growing tick times before the hang. The transition is binary: one tick healthy, next tick spinning at 100% until killed. We also did elimination testing — stopped/patched several suspected resources over multiple days (guards against calling natives on disconnected players, callback response guards) — the hangs continued regardless, with no correlation to any specific resource.
Source analysis: fx::AnyCast throws std::bad_any_cast on an empty/mismatched client data slot (Client.h:101). GET_PLAYER_PED and MakePlayerEntityFunction.h wrap it in try/catch, but state/ServerRPC.cpp has three uncaught call sites (approx. lines 179, 386, 623 on master):
if (cxtEntity < 0x20000)
{
auto client = clientRegistry->GetClientByNetID(cxtEntity);
if (client)
{
cxtEntity = fx::AnyCast<uint32_t>(client->GetData("playerEntity")); // <- uncaught
}
}
Trigger: a server script calls an RPC native with an entity argument that is a player netID whose client has no playerEntity (player still in connection/character selection, just dropped, or a script passing a player id instead of a ped). The uncaught exception propagates into ScriptNativeContext::Invoke() and svMain never recovers.
Regression window narrowed to one merge: b33864 ran a full week with zero hangs. Hangs started immediately on b34629, whose server-side delta is essentially mr-944 "Update libraries" with commit ae71946 ("feat(lua): updated libraries" — vendor/lua runtime bump + glm/cmsgpack/rapidjson). The follow-up Lua fixes from Aug 19–20 (0a2f63772, 3c1715467) are included in b35265 and did not resolve it. Our theory: the Lua runtime update changed error propagation across the C++/CfxLua boundary, so this pre-existing uncaught throw now loops forever instead of unwinding into a script error.
Expected result
An invalid native call should raise a script error for the calling resource, not hang the entire server at 100% CPU until txAdmin kills it.
Reproduction steps
- Run FXServer b34629 or newer (Linux, OneSync, ESX) with real player traffic.
- Have a player connected but without a player ped yet (e.g. sitting in a multicharacter selection screen, or mid-connection).
- Any server resource calls an RPC (entity) native whose entity argument resolves to that player's netID (< 0x20000) —
client->GetData("playerEntity") is empty → fx::AnyCast throws.
- svMain spins at 100% CPU throwing
std::bad_any_cast forever; txAdmin restarts the server after ~60s. Not reproducible on b33864 (same scripts, same trigger — unwinds as a normal script error there).
Importancy
Crash
Area(s)
FXServer
Specific version(s)
FXServer linux b34629, b34833, b35265 (all affected); b33864 NOT affected (last clean build). Bug present in current master (ServerRPC.cpp unchanged since 2024)
Additional information
Happy to provide full gdb transcripts, eu-stack dumps of the spinning thread, or test a diagnostic build. Adding a try/catch at the three ServerRPC.cpp sites (returning 0 like GET_PLAYER_PED does) would mitigate the symptom even before the unwind regression itself is addressed — the hang is far worse than the original bad call. Related report with matching symptoms but no diagnosis: # 3753
What happened?
FXServer's svMain thread enters an infinite loop at 100% CPU, repeatedly throwing
std::bad_any_cast, and never recovers. txAdmin kills the server after ~60s of missed heartbeats(Loop svMain seems hung!, watchdog stack: root). We captured 10+ occurrences over 6 days on a ~250-slot production server, at player counts from 4 to 199, at random times.gdb on the live spinning process (breakpoint
on __cxa_throw, fires repeatedly):A raw dump of the svMain stack during the spin contains the string literal "playerEntity". A full-heap scan finds no repeated Lua error strings — the exception never reaches script level; the engine re-throws forever.
This is not script load: resmon/profiler captures on the same days show a healthy server — total script time ~6–10% of svMain at 250 players, no resource above normal, no growing tick times before the hang. The transition is binary: one tick healthy, next tick spinning at 100% until killed. We also did elimination testing — stopped/patched several suspected resources over multiple days (guards against calling natives on disconnected players, callback response guards) — the hangs continued regardless, with no correlation to any specific resource.
Source analysis:
fx::AnyCastthrowsstd::bad_any_caston an empty/mismatched client data slot (Client.h:101).GET_PLAYER_PEDandMakePlayerEntityFunction.hwrap it in try/catch, but state/ServerRPC.cpp has three uncaught call sites (approx. lines 179, 386, 623 on master):Trigger: a server script calls an RPC native with an entity argument that is a player netID whose client has no playerEntity (player still in connection/character selection, just dropped, or a script passing a player id instead of a ped). The uncaught exception propagates into
ScriptNativeContext::Invoke()and svMain never recovers.Regression window narrowed to one merge: b33864 ran a full week with zero hangs. Hangs started immediately on b34629, whose server-side delta is essentially mr-944 "Update libraries" with commit ae71946 ("feat(lua): updated libraries" —
vendor/luaruntime bump + glm/cmsgpack/rapidjson). The follow-up Lua fixes from Aug 19–20 (0a2f63772,3c1715467) are included in b35265 and did not resolve it. Our theory: the Lua runtime update changed error propagation across the C++/CfxLua boundary, so this pre-existing uncaught throw now loops forever instead of unwinding into a script error.Expected result
An invalid native call should raise a script error for the calling resource, not hang the entire server at 100% CPU until txAdmin kills it.
Reproduction steps
client->GetData("playerEntity") is empty→fx::AnyCast throws.std::bad_any_cast forever; txAdmin restarts the server after ~60s. Not reproducible on b33864 (same scripts, same trigger — unwinds as a normal script error there).Importancy
Crash
Area(s)
FXServer
Specific version(s)
FXServer linux b34629, b34833, b35265 (all affected); b33864 NOT affected (last clean build). Bug present in current master (ServerRPC.cpp unchanged since 2024)
Additional information
Happy to provide full gdb transcripts, eu-stack dumps of the spinning thread, or test a diagnostic build. Adding a try/catch at the three ServerRPC.cpp sites (returning 0 like GET_PLAYER_PED does) would mitigate the symptom even before the unwind regression itself is addressed — the hang is far worse than the original bad call. Related report with matching symptoms but no diagnosis: # 3753