faulthandler — Дамп трассировки Python

Добавлено в версии 3.3.


Данный модуль содержит функции для явного сброса трассировки Python, при ошибке, после тайм-аута или по сигналу пользователя. Вызовите faulthandler.enable(), чтобы установить обработчики ошибок для сигналов SIGSEGV, SIGFPE, SIGABRT, SIGBUS и SIGILL. Вы также можете включить их при запуске, установив переменную среды PYTHONFAULTHANDLER или используя параметр командной строки -X faulthandler.

Обработчик ошибок совместим с системными обработчиками ошибок, такими как Apport или обработчик ошибок Windows. Модуль использует альтернативный стек для обработчиков сигналов, если доступна функция sigaltstack(). Это позволяет сбрасывать трассировку даже при переполнении стека.

Обработчик ошибок вызывается в аварийных случаях и поэтому может использовать только безопасные для сигналов функции (например, он не может выделять память в куче). Из-за этого ограничения дамп обратной трассировки минимален по сравнению с обычными обратными трассировками Python:

  • Поддерживается только ASCII. При кодировании используется обработчик ошибок backslashreplace.
  • Каждая строка ограничена 500 символами.
  • Отображаются только имя файла, имя функции и номер строки. (Без исходного кода.)
  • Он ограничен 100 фреймами и 100 потоками.
  • Порядок обратный: самый последний вызов отображается первым.

По умолчанию трассировка Python записывается в sys.stderr. Чтобы увидеть трассировку, приложения должны запускаться в терминале. В качестве альтернативы файл журнала можно передать на faulthandler.enable().

Модуль реализован на C, поэтому трассировка может быть сброшена при сбое или когда Python заблокирован.

Сброс трассировки

faulthandler.dump_traceback(file=sys.stderr, all_threads=True)

Сбрасывает трассировку всех потоков в file. Если all_threads равен False, дамп только текущего потока.

Изменено в версии 3.5: Добавлена поддержка передачи файлового дескриптора в эту функцию.

Состояние обработчика ошибок

faulthandler.enable(file=sys.stderr, all_threads=True)

Включает обработчик ошибок: устанавливает обработчики для сигналов SIGSEGV, SIGFPE, SIGABRT, SIGBUS и SIGILL, чтобы сбросить трассировку Python. Если all_threads равен True, создаёт обратные трассировки для каждого запущенного потока. В противном случае дамп только текущего потока.

file должен оставаться открытым, пока обработчик ошибок не будет отключён: см. Проблема с файловыми дескрипторами.

Изменено в версии 3.5: Добавлена поддержка передачи файлового дескриптора в эту функцию.

Изменено в версии 3.6: В Windows также установлен обработчик исключения Windows.

faulthandler.disable()

Отключает обработчик ошибок: удаляет обработчики сигналов, установленные enable().

faulthandler.is_enabled()

Проверяет, включён ли обработчик ошибок.

Сброс трассировки после тайм-аута

faulthandler.dump_traceback_later(timeout, repeat=False, file=sys.stderr, exit=False)

Создает дамп трассировки всех потоков после тайм-аута timeout секунд или каждые timeout секунд, если repeat равен True. Если exit — это True, вызывает _exit() со статусом = 1 после сброса трассировок. (Примечание _exit() немедленно завершает процесс, поэтому она не выполняет никакой очистки, такой как очистка файловых буферов.) Если функция вызывается дважды, новый вызов заменяет предыдущие параметры и сбрасывает тайм-аут. У таймера разрешение менее секунды.

file должен оставаться открытым до тех пор, пока не будет сброшена трассировка или не будет вызвана cancel_dump_traceback_later(): см. Проблема с файловыми дескрипторами.

Данная функция реализована с помощью сторожевого (watchdog) потока.

Изменено в версии 3.7: Теперь данная функция доступна всегда.

Изменено в версии 3.5: Добавлена поддержка передачи файлового дескриптора в эту функцию.

faulthandler.cancel_dump_traceback_later()

Отменяет последний вызов на dump_traceback_later().

Сброс трассировки по пользовательскому сигналу

faulthandler.register(signum, file=sys.stderr, all_threads=True, chain=False)

Регистрирует пользовательский сигнал: устанавливает обработчик для сигнала signum, чтобы сбросить трассировку всех потоков или текущего потока, если all_threads равен False, в file. Вызывает предыдущий обработчик, если цепочка True.

file должен оставаться открытым до тех пор, пока сигнал не будет снят с регистрации unregister(): см. Проблема с файловыми дескрипторами.

Недоступно в Windows.

Изменено в версии 3.5: Добавлена поддержка передачи файлового дескриптора в эту функцию.

faulthandler.unregister(signum)

Отменяет регистрацию пользовательского сигнала: удаляет обработчик сигнала signum, установленный register(). Возвращает True, если сигнал был зарегистрирован, False в противном случае.

Недоступно в Windows.

Проблема с файловыми дескрипторами

enable(), dump_traceback_later() и register() сохраняют файловый дескриптор аргумента file. Если файл закрывается и его файловый дескриптор повторно используется новым файлом, или если os.dup2() используется для замены файлового дескриптора, трассировка будет записана в другой файл. Вызывайте данные функции снова каждый раз при замене файла.

Пример

Пример ошибки сегментации в Linux с включенным обработчиком ошибок и без него:

$ python3 -c "import ctypes; ctypes.string_at(0)"
Segmentation fault

$ python3 -q -X faulthandler
>>> import ctypes
>>> ctypes.string_at(0)
Fatal Python error: Segmentation fault

Current thread 0x00007fb899f39700 (most recent call first):
  File "/home/python/cpython/Lib/ctypes/__init__.py", line 486 in string_at
  File "<stdin>", line 1 in <module>
Segmentation fault