#include "Python.h"
#include "pycore_initconfig.h"
#include "pycore_pyerrors.h"
#include "pycore_pystate.h"
#include "pycore_signal.h"
#include "pycore_sysmodule.h"
#include "pycore_time.h"
#include "pycore_traceback.h"
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <signal.h>
#include <stdlib.h>
#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK) && defined(HAVE_PTHREAD_H)
# include <pthread.h>
#endif
#ifdef MS_WINDOWS
# include <windows.h>
#endif
#ifdef HAVE_SYS_RESOURCE_H
# include <sys/resource.h>
#endif
#if defined(FAULTHANDLER_USE_ALT_STACK) && defined(HAVE_LINUX_AUXVEC_H) && defined(HAVE_SYS_AUXV_H)
# include <linux/auxvec.h>
# include <sys/auxv.h>
#endif
#define STACK_OVERFLOW_MAX_SIZE …
#define PUTS(fd, str) …
#if defined(__has_feature)
# if __has_feature(undefined_behavior_sanitizer)
#define _Py_NO_SANITIZE_UNDEFINED …
# endif
#endif
#if defined(__GNUC__) \
&& ((__GNUC__ >= 5) || (__GNUC__ == 4) && (__GNUC_MINOR__ >= 9))
#define _Py_NO_SANITIZE_UNDEFINED …
#endif
#ifndef _Py_NO_SANITIZE_UNDEFINED
#define _Py_NO_SANITIZE_UNDEFINED
#endif
fault_handler_t;
#define fatal_error …
#define thread …
#ifdef FAULTHANDLER_USER
#define user_signals …
user_signal_t;
static void faulthandler_user(int signum);
#endif
static fault_handler_t faulthandler_handlers[] = …;
static const size_t faulthandler_nsignals = …;
#ifdef FAULTHANDLER_USE_ALT_STACK
#define stack …
#define old_stack …
#endif
static int
faulthandler_get_fileno(PyObject **file_ptr)
{ … }
static PyThreadState*
get_thread_state(void)
{ … }
static void
faulthandler_dump_traceback(int fd, int all_threads,
PyInterpreterState *interp)
{ … }
static PyObject*
faulthandler_dump_traceback_py(PyObject *self,
PyObject *args, PyObject *kwargs)
{ … }
static void
faulthandler_disable_fatal_handler(fault_handler_t *handler)
{ … }
static void
faulthandler_fatal_error(int signum)
{ … }
#ifdef MS_WINDOWS
static int
faulthandler_ignore_exception(DWORD code)
{
if (!(code & 0x80000000)) {
return 1;
}
if (code == 0xE06D7363
|| code == 0xE0434352 ) {
return 1;
}
return 0;
}
static LONG WINAPI
faulthandler_exc_handler(struct _EXCEPTION_POINTERS *exc_info)
{
const int fd = fatal_error.fd;
DWORD code = exc_info->ExceptionRecord->ExceptionCode;
DWORD flags = exc_info->ExceptionRecord->ExceptionFlags;
if (faulthandler_ignore_exception(code)) {
return EXCEPTION_CONTINUE_SEARCH;
}
PUTS(fd, "Windows fatal exception: ");
switch (code)
{
case EXCEPTION_ACCESS_VIOLATION: PUTS(fd, "access violation"); break;
case EXCEPTION_FLT_DIVIDE_BY_ZERO: PUTS(fd, "float divide by zero"); break;
case EXCEPTION_FLT_OVERFLOW: PUTS(fd, "float overflow"); break;
case EXCEPTION_INT_DIVIDE_BY_ZERO: PUTS(fd, "int divide by zero"); break;
case EXCEPTION_INT_OVERFLOW: PUTS(fd, "integer overflow"); break;
case EXCEPTION_IN_PAGE_ERROR: PUTS(fd, "page error"); break;
case EXCEPTION_STACK_OVERFLOW: PUTS(fd, "stack overflow"); break;
default:
PUTS(fd, "code 0x");
_Py_DumpHexadecimal(fd, code, 8);
}
PUTS(fd, "\n\n");
if (code == EXCEPTION_ACCESS_VIOLATION) {
for (size_t i=0; i < faulthandler_nsignals; i++) {
fault_handler_t *handler = &faulthandler_handlers[i];
if (handler->signum == SIGSEGV) {
faulthandler_disable_fatal_handler(handler);
break;
}
}
}
faulthandler_dump_traceback(fd, fatal_error.all_threads,
fatal_error.interp);
return EXCEPTION_CONTINUE_SEARCH;
}
#endif
#ifdef FAULTHANDLER_USE_ALT_STACK
static int
faulthandler_allocate_stack(void)
{ … }
#endif
static int
faulthandler_enable(void)
{ … }
static PyObject*
faulthandler_py_enable(PyObject *self, PyObject *args, PyObject *kwargs)
{ … }
static void
faulthandler_disable(void)
{ … }
static PyObject*
faulthandler_disable_py(PyObject *self, PyObject *Py_UNUSED(ignored))
{ … }
static PyObject*
faulthandler_is_enabled(PyObject *self, PyObject *Py_UNUSED(ignored))
{ … }
static void
faulthandler_thread(void *unused)
{ … }
static void
cancel_dump_traceback_later(void)
{ … }
#define SEC_TO_US …
static char*
format_timeout(PyTime_t us)
{ … }
static PyObject*
faulthandler_dump_traceback_later(PyObject *self,
PyObject *args, PyObject *kwargs)
{ … }
static PyObject*
faulthandler_cancel_dump_traceback_later_py(PyObject *self,
PyObject *Py_UNUSED(ignored))
{ … }
#ifdef FAULTHANDLER_USER
static int
faulthandler_register(int signum, int chain, _Py_sighandler_t *previous_p)
{ … }
static void
faulthandler_user(int signum)
{ … }
static int
check_signum(int signum)
{ … }
static PyObject*
faulthandler_register_py(PyObject *self,
PyObject *args, PyObject *kwargs)
{ … }
static int
faulthandler_unregister(user_signal_t *user, int signum)
{ … }
static PyObject*
faulthandler_unregister_py(PyObject *self, PyObject *args)
{ … }
#endif
static void
faulthandler_suppress_crash_report(void)
{ … }
static PyObject* _Py_NO_SANITIZE_UNDEFINED
faulthandler_read_null(PyObject *self, PyObject *args)
{ … }
static void
faulthandler_raise_sigsegv(void)
{ … }
static PyObject *
faulthandler_sigsegv(PyObject *self, PyObject *args)
{ … }
static void _Py_NO_RETURN
faulthandler_fatal_error_thread(void *plock)
{ … }
static PyObject *
faulthandler_fatal_error_c_thread(PyObject *self, PyObject *args)
{ … }
static PyObject* _Py_NO_SANITIZE_UNDEFINED
faulthandler_sigfpe(PyObject *self, PyObject *args)
{ … }
static PyObject *
faulthandler_sigabrt(PyObject *self, PyObject *args)
{ … }
#if defined(FAULTHANDLER_USE_ALT_STACK)
#define FAULTHANDLER_STACK_OVERFLOW
static uintptr_t
stack_overflow(uintptr_t min_sp, uintptr_t max_sp, size_t *depth)
{ … }
static PyObject *
faulthandler_stack_overflow(PyObject *self, PyObject *Py_UNUSED(ignored))
{ … }
#endif
static int
faulthandler_traverse(PyObject *module, visitproc visit, void *arg)
{ … }
#ifdef MS_WINDOWS
static PyObject *
faulthandler_raise_exception(PyObject *self, PyObject *args)
{
unsigned int code, flags = 0;
if (!PyArg_ParseTuple(args, "I|I:_raise_exception", &code, &flags))
return NULL;
faulthandler_suppress_crash_report();
RaiseException(code, flags, 0, NULL);
Py_RETURN_NONE;
}
#endif
PyDoc_STRVAR(module_doc,
"faulthandler module.");
static PyMethodDef module_methods[] = …;
static int
PyExec_faulthandler(PyObject *module) { … }
static PyModuleDef_Slot faulthandler_slots[] = …;
static struct PyModuleDef module_def = …;
PyMODINIT_FUNC
PyInit_faulthandler(void)
{ … }
static int
faulthandler_init_enable(void)
{ … }
PyStatus
_PyFaulthandler_Init(int enable)
{ … }
void _PyFaulthandler_Fini(void)
{ … }