2025, Oct 01 19:17
Почему faulthandler показывает access violation в multiprocessing на Windows и как на это влияет антивирус
Разбираем access violation при старте multiprocessing на Windows: faulthandler и pytest показывают сбой, а причина в антивирусе (SentinelOne). Пример и решение.
Когда простой скрипт с multiprocessing в Windows выводит «Windows fatal exception: access violation», но при этом продолжает работу, это сбивает с толку. Сообщение появляется только при включённом faulthandler — поэтому в pytest оно заметно, тогда как при прямом запуске Python всё может выглядеть чисто. Ниже приведён минимальный пример, который воспроизводит поведение в Windows 10 и Windows 11 на Python 3.10 и 3.12.
Воспроизводимый пример
import multiprocessing as mp
import faulthandler
faulthandler.enable()
def worker_task():
    import os
    print(f"Worker PID: {os.getpid()}")
    print("Worker process completed")
def run_case():
    proc = mp.Process(target=worker_task)
    proc.start()
    proc.join()
    print(f"Process exit code: {proc.exitcode}")
if __name__ == "__main__":
    print("Direct run:")
    run_case()
    print("Success")
При включённом faulthandler в консоли появляется сообщение об ошибке доступа, в то время как процесс корректно завершается, и выполнение Python‑кода продолжается.
Что показывает трассировка
Windows fatal exception: access violation
Current thread 0x00000f48 (most recent call first):
  File "C:\Python\cpython-3.10.16-windows-x86_64-none\lib\multiprocessing\popen_spawn_win32.py", line 73 in __init__
  File "C:\Python\cpython-3.10.16-windows-x86_64-none\lib\multiprocessing\context.py", line 336 in _Popen
  File "C:\Python\cpython-3.10.16-windows-x86_64-none\lib\multiprocessing\context.py", line 224 in _Popen
  File "C:\Python\cpython-3.10.16-windows-x86_64-none\lib\multiprocessing\process.py", line 121 in start
  File "C:\src\sandbox\minimal.py", line 5 in test_reproduce
Это указывает на создание дочернего процесса и, в частности, на вызов _winapi.CreateProcess(). Иными словами, сообщение возникает вокруг запуска процесса, а не внутри вашего рабочего кода. Если faulthandler отключён, вы не увидите этот вывод при обычном запуске Python; pytest включает faulthandler за вас, делая сообщение видимым.
Первопричина в данном случае
Поведение вызвано антивирусным продуктом — агентом SentinelOne. Отключение агента убирало сообщение об access violation; повторное включение возвращало его. На другой системе с Windows 11 Pro и Python 3.12.10 без запущенного антивируса тот же код выполняется без этого сообщения. В качестве дополнительных проверок предлагалось запустить тривиальный subprocess и попробовать чистую установку Python, чтобы изолировать, связано ли это с multiprocessing или с окружением. Приведённый выше минимальный пример показывает, что проблема не зависит от того, что именно выполняет дочерний процесс.
Почему faulthandler это показывает
faulthandler предназначен для вывода низкоуровневых сбоёв, печатая диагностику в stderr. Поэтому пользователи pytest чаще замечают это сообщение: pytest включает faulthandler. Скрипт при этом продолжает выполняться и завершается без Python‑исключения, но вывод с access violation всё равно появляется.
Решение
В данном случае решение связано с окружением, а не с кодом. Отключение агента SentinelOne устранило вывод о нарушении доступа при создании процесса, а повторное включение снова его вызвало. Менять Python‑код не потребовалось.
Почему это важно для пользователей Windows, multiprocessing и pytest
При работе с multiprocessing в Windows сообщения, возникающие при запуске процесса, легко принять за сбои приложения. Если вы запускаете тесты под pytest, faulthandler делает такие низкоуровневые сигналы заметными, даже когда ваш код в остальном работает штатно. Знание о том, что агент антивируса может провоцировать такой вывод, помогает отличать ложные тревоги от реальных дефектов в логике рабочих процессов.
Выводы
Если при старте mp.Process вы видите «Windows fatal exception: access violation», а скрипт при этом завершается, учитывайте факторы окружения. В описанном случае триггером был агент SentinelOne. С отключённым faulthandler вы можете вовсе не заметить сообщение, тогда как pytest показывает его по умолчанию. Проверка на машине без антивируса, чистая установка Python или запуск тривиального subprocess — практичные способы подтвердить, что поведение не связано с вашим кодом.
Статья основана на вопросе со StackOverflow от kevinlinxc и ответе от kevinlinxc.