| #ifndef Py_INTERNAL_FAULTHANDLER_H | |
| #define Py_INTERNAL_FAULTHANDLER_H | |
| #ifdef __cplusplus | |
| extern "C" { | |
| #endif | |
| #ifndef Py_BUILD_CORE | |
| # error "this header requires Py_BUILD_CORE define" | |
| #endif | |
| #ifdef HAVE_SIGACTION | |
| # include <signal.h> // sigaction | |
| #endif | |
| #ifndef MS_WINDOWS | |
| /* register() is useless on Windows, because only SIGSEGV, SIGABRT and | |
| SIGILL can be handled by the process, and these signals can only be used | |
| with enable(), not using register() */ | |
| # define FAULTHANDLER_USER | |
| #endif | |
| #ifdef HAVE_SIGACTION | |
| /* Using an alternative stack requires sigaltstack() | |
| and sigaction() SA_ONSTACK */ | |
| # ifdef HAVE_SIGALTSTACK | |
| # define FAULTHANDLER_USE_ALT_STACK | |
| # endif | |
| typedef struct sigaction _Py_sighandler_t; | |
| #else | |
| typedef PyOS_sighandler_t _Py_sighandler_t; | |
| #endif // HAVE_SIGACTION | |
| #ifdef FAULTHANDLER_USER | |
| struct faulthandler_user_signal { | |
| int enabled; | |
| PyObject *file; | |
| int fd; | |
| int all_threads; | |
| int chain; | |
| _Py_sighandler_t previous; | |
| PyInterpreterState *interp; | |
| Py_ssize_t max_threads; | |
| }; | |
| #endif /* FAULTHANDLER_USER */ | |
| struct _faulthandler_runtime_state { | |
| struct { | |
| int enabled; | |
| PyObject *file; | |
| int fd; | |
| int all_threads; | |
| PyInterpreterState *interp; | |
| #ifdef MS_WINDOWS | |
| void *exc_handler; | |
| #endif | |
| int c_stack; | |
| Py_ssize_t max_threads; | |
| } fatal_error; | |
| struct { | |
| PyObject *file; | |
| int fd; | |
| PY_TIMEOUT_T timeout_us; /* timeout in microseconds */ | |
| int repeat; | |
| PyInterpreterState *interp; | |
| int exit; | |
| char *header; | |
| size_t header_len; | |
| Py_ssize_t max_threads; | |
| /* The main thread always holds this lock. It is only released when | |
| faulthandler_thread() is interrupted before this thread exits, or at | |
| Python exit. */ | |
| PyThread_type_lock cancel_event; | |
| /* released by child thread when joined */ | |
| PyThread_type_lock running; | |
| } thread; | |
| #ifdef FAULTHANDLER_USER | |
| struct faulthandler_user_signal *user_signals; | |
| #endif | |
| #ifdef FAULTHANDLER_USE_ALT_STACK | |
| stack_t stack; | |
| stack_t old_stack; | |
| #endif | |
| }; | |
| #define _faulthandler_runtime_state_INIT \ | |
| { \ | |
| .fatal_error = { \ | |
| .fd = -1, \ | |
| }, \ | |
| } | |
| #ifdef __cplusplus | |
| } | |
| #endif | |
| #endif /* !Py_INTERNAL_FAULTHANDLER_H */ |