Skip to content

pol.exe crashes under Windower 4 May 2026 stable — evidence report #1114

Description

@Cypan-Bahamut

pol.exe crashes under Windower 4 May 2026 stable — evidence report

Reporter: heavy Lua addon user. Reproducible daily since ~May 21, 2026; ten minidumps collected across many separate sessions, several of them instrumented. Report compiled Aug 4, 2026.

Summary

pol.exe crashes repeatedly, 25–100 minutes into use, in two recurring native modes: an AV in LuaCore's allocator/GC region (7 dumps, one EIP hit twice weeks apart), and an AV in the render path (3 dumps, same driver EIP each time). The same addon set had been in daily use for months without a crash before the May 18, 2026 Dev→Stable merge; first crash May 21, and 2–3 per day of use since.

The heaviest addon was instrumented in-state and its Lua side is clean: balanced event registrations, no handler leak, flat live heap. Six Lua-side hypotheses were tested and eliminated one at a time — handler leaks, coroutine-object churn, scheduler registration rate, packet parse volume, windower.ffxi.run()/follow() call rate, heap retention — each reduced 10–100x with no change in crash timing. Details under Instrumentation.

Environment

  • Windows 10 x86 process (pol.exe 32-bit), Steam FFXI
  • Windower 4, May 18 2026 stable (the big Dev merge), plus subsequent hook patches
  • Large Address Aware: OFF (verified in launcher)
  • Plugins: LuaCore, Hook, DelayMeNot, FFXIDB, JaZero, PacketFlow, Timers
  • NVIDIA GPU (nvwgf2um.dll user-mode driver in-process)

Crash Mode A — LuaCore, allocator/GC region (7 dumps)

All EIPs land in the same ~0xA0000–0xAA000 region of LuaCore.dll, with GC/alloc-looking call chains on the stack; faults are AV reads either at small offsets (0x6–0x15) off null/garbage registers or at wild addresses.

Date (UTC) EIP (LuaCore+) Fault Notes
May 24 17:13 0xA6C83 read @ 0x7, ECX=0 pre-rebuild offsets
May 25 07:20 0x28244 read @ 0x7, ECX=7 Hook.dll frames on stack
May 25 14:25 0x10703 WRITE @ addr inside LuaCore's own image Hook.dll frames (incoming-packet path)
Jul 29 20:30 0xA616E read @ 0xD post-rebuild offsets
Jul 30 01:46 0xA9B13 read (wild)  
Aug 03 19:16 0xA9B13 read @ 0x6A7F4A90 same EIP as Jul 30
Aug 03 21:52 0xA76F0 read @ 0xC0880000 wild value in 3 registers
Aug 03 23:47 0xA0A8B read @ 0x15, EDX=0 crashed while stationary

*different driver build in May. No Windower or Lua frames on the crashing thread in this mode; near-null base register with a small field offset. Driver version unchanged across the May→Aug window per the user; the mode predates and postdates a LuaCore rebuild.

Instrumentation (how we know the Lua side is clean)

Two recorders ran for the Aug 3 sessions:

  1. An external addon logging ms-timestamped packets, chat, entity spawn/despawn, frame hitches, and heartbeats, flushed per line (tails survive the crash and align with dump timestamps to ~1s).
  2. An in-state module inside the busiest addon's Lua state wrapping windower.register_event / unregister_event / coroutine.schedule, logging live-handler counts with file:line attribution, schedule-origin counts, and collectgarbage('count') every 2s.

Findings across instrumented crash sessions:

  • Event handlers: fully balanced (e.g. 1091 registered / 1086 unregistered, live steady at baseline 5–7). No leak.
  • coroutine.schedule volume: originally ~7,500/session (one helper re-invoked itself via coroutine.schedule every 0.1s whenever the character was moving); refactored stepwise down to 94/session. Crash MTBF unchanged at every step.
  • Final measured state of the busiest addon in one instrumented crash session: 191 coroutine.schedule calls total; event handlers 3,166 registered / 3,159 unregistered with live count steady at 6–7; live Lua heap flat per above. Every Lua-side load we can control is now minimal and measurably balanced, and MTBF is unchanged from the un-refactored baseline.
  • Incoming 0x075 arrives ~7/sec continuously in the affected content (in bursts of 3–4 identical payloads); per-packet parsing was deduplicated. MTBF unchanged.
  • windower.ffxi.run()/follow() call rate while moving was reduced stepwise from ~10/sec each to ~1/sec run() (re-issued only on material direction change or a 1s keepalive) plus a single follow() per movement — a 50–100x reduction in calls into the run/follow path reworked in the May stable. MTBF unchanged; one Mode A crash occurred while the character was stationary.
  • Lua heap: NOT leaking. One session forced 34 full collections (collectgarbage('collect')); post-collect heap was flat at 31.0MB ± 0.1MB across all 34 (total drift 415KB). The 35–50MB seen in addon memory listings is ordinary sawtooth float. That session still crashed, 55 seconds after the last forced collect — i.e. not GC-triggered and not memory-correlated.
  • Menu-driven NPC interactions intermittently fail late-session (event-skip detection, menu response timeouts) — echoes the dropped-packet reports that caused the January 2026 stable revert.

Timeline correlation

  • May 11–12: FFXI version update. No crashes.
  • May 18: Windower Dev→Stable merge (reintroducing the reverted January changes, including the LuaCore run()/follow() rework: "Fixed jumping and crashing issues with windower.ffxi.run(); run vector properly cleared on run(false)/follow(false)"), followed by several hook patches.
  • May 21–22: first crashes (inferred from log session analysis); confirmed dumps from May 24 onward. 2–3 crashes per day of use since.

Questions for the team

  1. Can you resolve the Mode A EIPs against LuaCore PDBs (both the pre- and post-July builds)? +0xA9B13 (x2), +0xA76F0, +0xA616E, +0xA0A8B, and the write at +0x10703 would identify the corrupted structure immediately.
  2. What are the exact semantics of no-arg windower.ffxi.follow() after the run/follow rework, and is run-vector clearing synchronized against the game thread's reads?
  3. Is the Hook incoming-packet path (dumps of May 25 and Jul 30) known to have changed in the May stable?
  4. Mode B: any known interaction between the May changes and the D3D8 wrapper path (FFXiMain+0xC0280 → D3D8 → d3d11 → nvwgf2um+0x1DB392 recurring)?

Available on request

All ten .dmp files. Also available: the raw counter series behind the instrumentation figures above (handler registration/unregistration counts, coroutine.schedule totals, per-collection heap measurements), and packet histograms with ms timestamps around each crash. Happy to run additional instrumented sessions capturing whatever specific measurements would help.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions