• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef Py_INTERNAL_FAULTHANDLER_H
2 #define Py_INTERNAL_FAULTHANDLER_H
3 #ifdef __cplusplus
4 extern "C" {
5 #endif
6 
7 #ifndef Py_BUILD_CORE
8 #  error "this header requires Py_BUILD_CORE define"
9 #endif
10 
11 #ifdef HAVE_SIGACTION
12 #  include <signal.h>             // sigaction
13 #endif
14 
15 
16 #ifndef MS_WINDOWS
17    /* register() is useless on Windows, because only SIGSEGV, SIGABRT and
18       SIGILL can be handled by the process, and these signals can only be used
19       with enable(), not using register() */
20 #  define FAULTHANDLER_USER
21 #endif
22 
23 
24 #ifdef HAVE_SIGACTION
25 /* Using an alternative stack requires sigaltstack()
26    and sigaction() SA_ONSTACK */
27 #  ifdef HAVE_SIGALTSTACK
28 #    define FAULTHANDLER_USE_ALT_STACK
29 #  endif
30 typedef struct sigaction _Py_sighandler_t;
31 #else
32 typedef PyOS_sighandler_t _Py_sighandler_t;
33 #endif  // HAVE_SIGACTION
34 
35 
36 #ifdef FAULTHANDLER_USER
37 struct faulthandler_user_signal {
38     int enabled;
39     PyObject *file;
40     int fd;
41     int all_threads;
42     int chain;
43     _Py_sighandler_t previous;
44     PyInterpreterState *interp;
45 };
46 #endif /* FAULTHANDLER_USER */
47 
48 
49 struct _faulthandler_runtime_state {
50     struct {
51         int enabled;
52         PyObject *file;
53         int fd;
54         int all_threads;
55         PyInterpreterState *interp;
56 #ifdef MS_WINDOWS
57         void *exc_handler;
58 #endif
59     } fatal_error;
60 
61     struct {
62         PyObject *file;
63         int fd;
64         PY_TIMEOUT_T timeout_us;   /* timeout in microseconds */
65         int repeat;
66         PyInterpreterState *interp;
67         int exit;
68         char *header;
69         size_t header_len;
70         /* The main thread always holds this lock. It is only released when
71            faulthandler_thread() is interrupted before this thread exits, or at
72            Python exit. */
73         PyThread_type_lock cancel_event;
74         /* released by child thread when joined */
75         PyThread_type_lock running;
76     } thread;
77 
78 #ifdef FAULTHANDLER_USER
79     struct faulthandler_user_signal *user_signals;
80 #endif
81 
82 #ifdef FAULTHANDLER_USE_ALT_STACK
83     stack_t stack;
84     stack_t old_stack;
85 #endif
86 };
87 
88 #define _faulthandler_runtime_state_INIT \
89     { \
90         .fatal_error = { \
91             .fd = -1, \
92         }, \
93     }
94 
95 
96 #ifdef __cplusplus
97 }
98 #endif
99 #endif /* !Py_INTERNAL_FAULTHANDLER_H */
100