Jump to content

Coop dedicated server crash (silent exit, code 42) — root cause found in the AI DLL, and a workaround


ShuhartProfit8ird

Recommended Posts

I hope this turns out to be useful to someone here. I'm building a small LAN
server with bots for me and a few friends, ran into the coop crash everyone
knows about, and ended up chasing it a lot further than I meant to. Posting it
in case it helps the community — and honestly in the hope that between us we
can turn it into something properly useful, because I've taken it about as far
as I can on my own.

Short version: the BF2 dedicated server doesn't exit on purpose when it dies in
coop — it crashes, and the engine catches its own access violation with an
__except wrapped around the whole game loop, then returns the constant 42. That
is why nothing is ever logged: no dialog, no Event Log entry, no WER, and the
dmp folder stays empty.

The bug underneath is in AIDLL_w32ded.dll. A pathfinder lookup indexes an array
with -1 — the engine's own "not found" value — so it reads the heap block header
sitting in front of the vector's buffer and hands that back as an object pointer.
Dereferencing it is the crash. Nothing is corrupted; the container is intact.
A sibling function sixty bytes away in the same file checks for -1 twice before
doing the identical indexing.

Measured on retail 1.5.3153-802.0, gpm_coop, 32 bots, same map both ways:

  without the workaround: 47.7 / 60.9 / 83.2 / 155.7 s — median 72 s,
                          zero rounds completed out of four
  with it:                17.4 minutes, two full rounds, zero exceptions

Full write-up with byte offsets, the disassembly and buildable code:
https://github.com/ShuhartProfit8ird/bf2-coop-crash

Two things you can do without taking my word for it:

1. Add "+seh 0" to your server command line. That switch exists in the retail
   binary and disables the top-level __except. The next crash then becomes an
   ordinary unhandled exception — WER fires, an event appears, and
   "procdump -ma -e -w bf2_w32ded.exe" gets you a full dump with a stack. One
   round tells you whether you're hitting this defect or a different one.

2. Check the byte signature at AIDLL_w32ded.dll+0x167AE0:
   55 8B EC 57 8B 79 7C 85 FF 75 07 32 C0
   If it matches, you have the same code.

Caveats, stated up front: this is a workaround, not a fix — the missing check is
still missing, and what makes that first "-1" appear two or three minutes in is
still open. I tested on a vanilla 1.5 dedicated server; I have NOT tested this
on PR or any other mod, so I don't know whether you hit the same path. The
signature check above answers that in a few seconds.

I'm not a programmer — this was found with an AI assistant reading the
disassembly, and everything is either a byte offset you can verify or a
measurement described precisely enough to repeat. Corrections very welcome,
especially from anyone who's been running these servers longer than I have.
Link to comment
Share on other sites

  • Replies 0
  • Created
  • Last Reply

Top Posters In This Topic

Popular Days

Top Posters In This Topic

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

Terms of Use and Privacy Policy