FEX-Emu / FEX-Emu/FEX

[World of Warcraft Classic Era] Infinite SIGSEGV/SIGILL loop in WowClassic_loader.dll on DGX Spark (GB10) — related to #5328

Open
#5,952 0 comments 0 reactions 0 assignees View on GitHub
Game related ml-report
Dominant language
C++
Stars
8k
Forks
351
Avg merge
12h 31m
Merged PRs (30d)
102

Description

**What Game**

World of Warcraft Classic Era — `_classic_era_/WowClassic.exe`

Storefront: https://www.blizzard.com/en-us/games/wow-classic — installed through the Battle.net client, which was itself run as a non-Steam game under Proton.

**Describe the bug**

`WowClassic.exe` starts but never presents a window. The process stays alive indefinitely at ~120% CPU across 8 threads, looping forever on an alternating signal pair:

```
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=NULL} ---
--- SIGILL {si_signo=SIGILL, si_code=ILL_ILLOPC, si_addr=0xc943550f4408} ---
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=NULL} ---
--- SIGILL {si_signo=SIGILL, si_code=ILL_ILLOPC, si_addr=0xc943550f4408} ---
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=NULL} ---
--- SIGILL {si_signo=SIGILL, si_code=ILL_ILLOPC, si_addr=0xc943550f4408} ---
```

The SIGILL address is fixed within a run and varies between runs (ASLR), so the loop makes no forward progress. Both signals are caught and returned from via `rt_sigreturn` — nothing crashes, the process simply never exits the loop. Left alone, one instance accumulated 58 minutes of CPU time without ever drawing a window.

Full context from a single iteration:

```
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=NULL} ---
rt_sigprocmask(SIG_SETMASK, ~[], [HUP INT USR1 SEGV USR2 ALRM CHLD IO], 8) = 0
rt_sigprocmask(SIG_SETMASK, [HUP INT USR1 SEGV USR2 ALRM CHLD IO], NULL, 8) = 0
rt_sigreturn({mask=[HUP INT USR1 USR2 ALRM CHLD IO]}) = 247086528336960
--- SIGILL {si_signo=SIGILL, si_code=ILL_ILLOPC, si_addr=0xc943550f4408} ---
rt_sigreturn({mask=[]}) = 247086528336960
```

Other threads in the process sit idle in `futex_waitv` / `pselect6` / `readv` throughout — only the main thread spins.

The game creates no `Logs/` or `Errors/` directory, and Proton's log records no unhandled exception. Both binaries load successfully:

```
trace:loaddll:build_module Loaded L"...\_classic_era_\WowClassic.exe" at 0000000140000000: native
trace:loaddll:build_module Loaded L"...\_classic_era_\WowClassic_loader.dll" at 00006FFFFA3C0000: native
```

Immediately before the loop begins, the Wine SEH trace shows exception `c0000420` (STATUS_ASSERTION_FAILURE) raised inside `WowClassic_loader.dll`, dispatched to a vectored handler which returns 1, followed by `RtlRestoreContext` resuming normally:

```
trace:seh:call_seh_handlers calling handler 00006FFFFC2CC094 (rec=..., frame=8b7fce0 ...)
trace:seh:RtlUnwindEx code=c0000420 flags=2 end_frame=0000000008B7FCE0 target_ip=00006FFFFBA028CF
warn:seh:virtual_unwind backtrace: 00006FFFFA789119: L"WowClassic_loader.dll" + 00000000003C9119.
warn:seh:virtual_unwind backtrace: 00006FFFFBA028CF: L"WowClassic_loader.dll" + 00000000016428CF.
trace:seh:RtlUnwindEx handler 00006FFFFC2CC094 returned 1
trace:seh:RtlRestoreContext returning to 00006FFFFBA028CF stack 0000000008B7FCE0
```

The final line written to the Proton log, roughly half a second later:

```
fixme:sfc:SfcIsFileProtected (0000000000000000, L"...\_classic_era_\WowClassic.exe") stub
```

Nothing is logged after that point — the process is still alive and spinning, but produces no further output.

This may be related to #5328 (WoW Classic `_anniversary_` on Winlator + FEX): same game family, same `WowClassic_loader.dll`, loader loads successfully and then enters an infinite exception loop. Filing separately because both the platform (DGX Spark / Linux / Proton, rather than Winlator / Android) and the signal signature (SIGSEGV+SIGILL pair, rather than a NoExec + C0000005 storm) differ. Also possibly adjacent to #5512 (SC2 x64 on DGX Spark), a different Blizzard title failing in its protected startup path on the same hardware.

**To Reproduce**

1. Install the Canonical arm64 Steam snap on an NVIDIA DGX Spark (GB10) running DGX OS.
2. In Steam, add `Battle.net-Setup.exe` as a non-Steam game and force a Proton version under Properties → Compatibility.
3. Launch it, let Battle.net install and sign in, then install World of Warcraft Classic Era.
4. Press Play on WoW Classic Era in Battle.net.
5. No window ever appears. `pgrep -if wowclassic` shows `WowClassic.exe` alive; `ps -o pid,stat,pcpu,etime,comm` shows state `R` at ~120% CPU.
6. `sudo strace -f -p ` shows the SIGSEGV/SIGILL loop above.

Additional notes on reproduction:

- Launching `WowClassic.exe` directly as a separate non-Steam game (with `STEAM_COMPAT_DATA_PATH` pointed at the same prefix) fails identically, so the Battle.net agent is not a factor. The Agent's own log confirms it spawns the game with real PIDs — the launch itself succeeds.
- Battle.net's Agent records the install as complete (`OP_UPDATE for 'wow_classic_era' completed`), and `AgentErrors` contains only benign Wine noise (`SetSecurityInfo` ACL failures and `.product.db` probes of non-Blizzard directories).
- Steam's "Stop" button does not terminate the hung process — it must be killed with `pkill -if wowclassic`. Three orphaned instances accumulated this way before I noticed.

**Expected behavior**

The game launches and presents its login window.

**Screenshots and Video**

Not applicable — no window is ever created, on any port or display.

**System information:**

- OS: DGX OS 7.5.0 (Ubuntu 24.04 based), kernel 6.17.0-1032-nvidia, aarch64
- CPU/SoC: NVIDIA GB10 Grace Blackwell — 10x Cortex-X925 (3.9 GHz) + 10x Cortex-A725 (2.8 GHz), 128 GB unified LPDDR5X
- Video driver version: NVIDIA 580.173.02 (`nvidia-driver-580-open`), CUDA 13.0, Vulkan loader 1.4.328, device reports `apiVersion 1.4.312`, `driverID DRIVER_ID_NVIDIA_PROPRIETARY`
- RootFS used: bundled with the Canonical arm64 Steam snap 1.0.0.85 rev 245 (latest/stable); `gaming-graphics-core24` 25.3.1~kisak1~n rev 19
- FEX version: **2603** (`FEXGetConfig --version` reports `2603`)
- Thunks Enabled: No — the Canonical snap ships thunking disabled by default and I have not changed it

**Additional context**

- Is this an x86 or x86-64 game: x86-64 (retail WoW Classic Era is 64-bit only; there is no 32-bit client to fall back to, unlike the SC2 case in #5512)
- Does this reproduce on AArch64 with Radeon/Intel/Nvidia: Nvidia (GB10). Untested on Radeon or Intel — I don't have other AArch64 hardware.
- Is this a Vulkan game: Yes, indirectly — WoW's own renderer is DX11/DX12, reaching Vulkan through DXVK / VKD3D-Proton
- If Yes, What is your Vulkan driver: NVIDIA proprietary 580.173.02. `vulkaninfo --summary` reports `NVIDIA GB10`, `PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU`, `conformanceVersion 1.4.1.3`, with `nvidia-drm modeset=1`.

**Proton versions tested — all fail identically**

| Proton version | Result |
|---|---|
| Proton Experimental | SIGSEGV/SIGILL loop, ~120% CPU, no window |
| Proton 10.0 | Identical |
| Proton Hotfix | Identical |

Same signal pair and same fixed-address loop in all three, so the Wine layer does not appear to be the variable here.

**Note on FEX version — why I could not test 2608/2609**

I am aware 2603 is several releases behind, and that FEX-2608 in particular contains changes that looked potentially relevant to a NULL-address SIGSEGV (the inactive JIT guard page fix, and the VirtualProtect fix under WINE). I was unable to test a newer FEX on this configuration:

- The Canonical arm64 Steam snap pins FEX 2603. All channels — `latest/stable`, `latest/candidate`, `latest/edge` — currently sit on revision 245 (published 2026-04-09, promoted to stable 2026-06-02), so `snap refresh` offers no newer build.
- GE-Proton11-6-aarch64, which bundles a newer FEX, cannot be used inside the snap. Its `toolmanifest.vdf` declares `require_tool_appid 4185400`; the snap's installed runtimes are `SteamLinuxRuntime`, `SteamLinuxRuntime_4`, `SteamLinuxRuntime_sniper` and `SteamLinuxRuntime_soldier`. Steam reports a compatibility tool failure, and requesting the missing runtime via `steam://install/4185400` produces no entry in `content_log.txt`.

If there's a supported way to get a current FEX onto this configuration, I'm happy to retest and report back — the hardware is available for testing.

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the failure on the listed DGX Spark configuration with FEX 2603 and capture the main-thread signal loop using strace. Compare the behavior across the tested Proton versions and the mentioned FEX changes; done means identifying and correcting the emulator or signal-handling cause so WowClassic_loader.dll reaches its login window without spinning.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, linux
Domain
operating-systems
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.