Возможно я починил кооперативные сервера BF2.
Делаю личный LAN проект BF2 на основе ваниллы: 64 бота на карте, умный ИИ и все такое без сильной переделки самого кор. геймплея. Делаю через ИИ и мы столкнулись с сильной проблемой, которая, походу, мучает сообщество уже 20 лет. Сервер падает без видимой ошибки.
Статья будет полезна тем, кто делал сервера / ставил моды и сталкивался со странными крашами.
Суть проблемы: кооп сервер Battlefield 2 умирает через минуту-две боя. Ни диалога, ни дампа, ни записи в журнале Windows — процесс просто исчезает с кодом 42.
ИИ разобрал бинарь и выяснил: код 42 — это краш, который движок ловит сам. Тело main обёрнуто в __try/__except, фильтр принимает что угодно, а 42 — константа в обработчике..
Под этим — ошибка в ИИ-пайпфайндере. Он честно отвечает «цель не на навмеше» значением −1, кладёт его в кэш, а потом использует как индекс массива. begin[-1] читает служебный заголовок блока кучи и эти восемь байт разыменовываются как объект.
Детальный разбор проблемы и решения (писал на английском):
В статье: цепочка из пяти вызовов с адресами и байтами, недокументированный ключ +seh 0 (включает нормальные краши вместо тишины), сломанный с 2005 года путь записи дампов, готовый код обхода и замеры.
Было: медиана жизни сервера 72 секунды, ноль доигранных раундов из четырёх. Стало: полные раунды, ноль аппаратных исключений, заплатка срабатывает 6042 раза за раунд — и каждое из этих обращений раньше было бы смертельным.