1
Issue Key
State
Access
Public
Group
Project
Creator
Created
Aug 17, 2026
Views
4Attachments
No attachments
Platform
Game Version
Mission
Is it modded?
List mods
175 mods (community milsim modset). Full list available on request. This is NOT a mod issue: the fault is a native access violation inside the engine's own explosion-query code, with no script frame anywhere in the stack, and element 0 of the faulting array is a base-game gamecode::Tree. A mod cannot author the faulting instruction.
Description
SUMMARY
A 50-slot modded Linux dedicated server took a SIGSEGV on its main thread (enfMain) inside the fixed-timestep world update. The server was completely healthy at the moment of death: the -logStats sample 397 ms earlier read 59.2 FPS, 16.9 ms frame time, 503 MB resident, 2 players, 10 AI. No degradation of any kind beforehand, and no script Virtual Machine Exception at the crash. It is a cliff, not a slope.
The fault is a read of address 0 in a native routine that sorts world-entity pointers by distance from an explosion origin, reached from gamecode::ExplosionQueryIterator. The sort selects a median-of-three pivot, that array slot contained NULL, and the code dereferences it with no null check.
ENVIRONMENT
Build 1.8.0.10 / 191843, Linux dedicated server. 2 players, 10 AI at crash time. Server args: -maxFPS=60 -noSound -noPause -logStats=10000.
THE FAULT
Kernel: enfMain[565035]: segfault at 0 ip 00000000009f8e5f sp 00007ffc6af9a1d0 error 4 in ArmaReforgerServer[400000+2f6f000] (error 4 = user-mode read of an unmapped page)
systemd: Main process exited, code=dumped, status=11/SEGV
The faulting routine begins at 0x9f8da0. Disassembly around the fault:
0x9f8e40 shr $1,%eax ; pivot index = count / 2
0x9f8e42 lea 0x0(,%rax,8),%r12
0x9f8e4a add %rbp,%r12
0x9f8e4d mov 0x0(%rbp),%rdi ; elem[0]
0x9f8e51 mov 0x0(%rbp,%rax,8),%r15 ; elem[pivot], pivot = 459
0x9f8e56 mov (%rdi),%rax ; elem[0] vtable
0x9f8e59 call *0xb8(%rax) ; virtual position getter
0x9f8e5f mov (%r15),%rcx ; <-- FAULTS, r15 == 0
0x9f8e62 movss 0x0(%r13),%xmm0 ; vec3 distance compare
Register state from NT_PRSTATUS: rip=0x9f8e5f, r15=0x0, rbp=0x7b25c8893000, r12=0x7b25c8893e58 (= rbp + 459*8), r13=rsi=0x7b25cfb96358, rdi=0x7b25ac5b93e0, rax=0x7b25ac5b948c (= rdi+0xAC).
The only guards in the entire function are a count >= 2 test and an n < 9 insertion-sort cutoff. There is no null check on the pivot or on the compared elements.
CALLER CHAIN
Recovered from the crash stack; the return address at rsp+0x2b8 is consistent with the function's 6 pushes plus sub $0x288, so this is the true caller frame rather than a stack-scan artifact:
0x9f8da0 (the sort) <- 0x9f6fc0 <- gamecode::ExplosionQueryIterator (vtable 0x25b9920, slot 0 = 0x9f6ee0) <- enf::BaseWorld (0xe94ec0) <- gamecode::ChimeraWorld (0x4d1730) <- gamelib::Game (0x1a8c4d0) <- Arma4App (0x1a974b0)
Class identities were recovered from RTTI in the shipped stripped binary, so no BI symbols were needed and these offsets should resolve directly on your side.
THE ARRAY IS STRUCTURALLY INCONSISTENT (we believe this is the actual defect)
The sort context declares 918 elements (ctx+0xE4 = 0x396; capacity ctx+0xE0 = 0x4FF = 1279), but of those 918 slots only 678 hold plausible object pointers:
slots 0-318 pointers
slot 319 zero
slots 320-423 NON-POINTER data, 104 slots (e.g. slot 420 = 0x44d0003bbf401179, which decodes as the float pair -0.7503 / 1664.0072)
slots 424-553 zero, 130 contiguous
slots 554-638 pointers
slots 639-660 zero, 22 contiguous
slots 661-917 pointers
slots 918-1799 zero (beyond the declared count)
Totals within the declared 918: 678 pointer, 153 zero, 87 non-pointer. The median-of-three pivot at index 459 lands in the middle of the 130-slot zero run.
The zeros come in contiguous RUNS rather than scattered singletons, and 87 slots hold what look like float pairs rather than pointers. That does not look like "an entity died and its handle was nulled". It looks like an element count that does not match how much of the buffer was actually filled, or a buffer reused between stages of the query without the count being reset.
Element 0 is a live, valid gamecode::Tree at (2713.228, 6.000, 2423.498), 69.8 m from the sort reference position (2644.265, 13.236, 2431.144) - so the populated entries are sane.
All 32 worker threads were parked in libc futex waits at fault time, so the buffer was in its final state, not caught mid-fill by the sort.
TRIGGER
Large-radius ordnance detonating over dense forest (the array is full of trees). Not reproducible on demand: the same ordnance type fired twice earlier in the same session with LARGER projectile counts and did not crash, and a second server on the same host ran the same content concurrently at 18 players without incident.
POSSIBLY RELATED
ARGF-368 (engine crash, resource/entity streaming use-after-free under network replication) describes garbage-pointer access violations with no script stack. Ours differs in the specifics - a clean NULL at address 0, in FixedFrame rather than ProcessNetToGame, with an identified function - but a partially-populated or reused buffer is consistent with that family, so this may be a precisely-characterised instance of the same underlying lifetime bug.
WHAT WOULD HELP EVEN WITHOUT A REPRO
A null check on the pivot and on the compared elements in that sort would turn a server-killing SIGSEGV into, at worst, a mis-ordered damage query. The deeper fix is whatever publishes the element count for that buffer.
ATTACHMENTS
Full console.log, script.log, error.log, crash.log and a 782 MB OS-level core dump are retained and can be supplied on request, along with the mod list. Note this particular crash produced no uploaded crash GUID: our unit had a read-only /tmp so the engine minidump could not be written and the auto-reporter received a 400 ValidationFailed. That has since been fixed on our side and subsequent crashes upload normally.
You are not signed in. Please sign in to see more details.
Issue Key
State
Access
Public
Group
Project
Creator
Created
Aug 17, 2026
Views
4Attachments
No attachments