mirror of https://github.com/python/cpython
gh-81057: Move faulthandler Globals to _PyRuntimeState (gh-100152)
https://github.com/python/cpython/issues/81057
This commit is contained in:
parent
8790d4d31f
commit
53d9cd95cd
|
@ -0,0 +1,99 @@
|
||||||
|
#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>
|
||||||
|
#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;
|
||||||
|
};
|
||||||
|
#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
|
||||||
|
} 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;
|
||||||
|
/* 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 */
|
|
@ -13,6 +13,7 @@ extern "C" {
|
||||||
#include "pycore_dict_state.h" // struct _Py_dict_runtime_state
|
#include "pycore_dict_state.h" // struct _Py_dict_runtime_state
|
||||||
#include "pycore_dtoa.h" // struct _dtoa_runtime_state
|
#include "pycore_dtoa.h" // struct _dtoa_runtime_state
|
||||||
#include "pycore_floatobject.h" // struct _Py_float_runtime_state
|
#include "pycore_floatobject.h" // struct _Py_float_runtime_state
|
||||||
|
#include "pycore_faulthandler.h" // struct _faulthandler_runtime_state
|
||||||
#include "pycore_function.h" // struct _func_runtime_state
|
#include "pycore_function.h" // struct _func_runtime_state
|
||||||
#include "pycore_global_objects.h" // struct _Py_global_objects
|
#include "pycore_global_objects.h" // struct _Py_global_objects
|
||||||
#include "pycore_import.h" // struct _import_runtime_state
|
#include "pycore_import.h" // struct _import_runtime_state
|
||||||
|
@ -140,6 +141,7 @@ typedef struct pyruntimestate {
|
||||||
struct _getargs_runtime_state getargs;
|
struct _getargs_runtime_state getargs;
|
||||||
struct _dtoa_runtime_state dtoa;
|
struct _dtoa_runtime_state dtoa;
|
||||||
struct _fileutils_state fileutils;
|
struct _fileutils_state fileutils;
|
||||||
|
struct _faulthandler_runtime_state faulthandler;
|
||||||
struct _tracemalloc_runtime_state tracemalloc;
|
struct _tracemalloc_runtime_state tracemalloc;
|
||||||
|
|
||||||
PyPreConfig preconfig;
|
PyPreConfig preconfig;
|
||||||
|
|
|
@ -54,6 +54,7 @@ extern "C" {
|
||||||
.fileutils = { \
|
.fileutils = { \
|
||||||
.force_ascii = -1, \
|
.force_ascii = -1, \
|
||||||
}, \
|
}, \
|
||||||
|
.faulthandler = _faulthandler_runtime_state_INIT, \
|
||||||
.tracemalloc = _tracemalloc_runtime_state_INIT, \
|
.tracemalloc = _tracemalloc_runtime_state_INIT, \
|
||||||
.float_state = { \
|
.float_state = { \
|
||||||
.float_format = _py_float_format_unknown, \
|
.float_format = _py_float_format_unknown, \
|
||||||
|
|
|
@ -1634,6 +1634,7 @@ PYTHON_HEADERS= \
|
||||||
$(srcdir)/Include/internal/pycore_descrobject.h \
|
$(srcdir)/Include/internal/pycore_descrobject.h \
|
||||||
$(srcdir)/Include/internal/pycore_dtoa.h \
|
$(srcdir)/Include/internal/pycore_dtoa.h \
|
||||||
$(srcdir)/Include/internal/pycore_exceptions.h \
|
$(srcdir)/Include/internal/pycore_exceptions.h \
|
||||||
|
$(srcdir)/Include/internal/pycore_faulthandler.h \
|
||||||
$(srcdir)/Include/internal/pycore_fileutils.h \
|
$(srcdir)/Include/internal/pycore_fileutils.h \
|
||||||
$(srcdir)/Include/internal/pycore_floatobject.h \
|
$(srcdir)/Include/internal/pycore_floatobject.h \
|
||||||
$(srcdir)/Include/internal/pycore_format.h \
|
$(srcdir)/Include/internal/pycore_format.h \
|
||||||
|
|
|
@ -18,12 +18,6 @@
|
||||||
# include <sys/resource.h>
|
# include <sys/resource.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Using an alternative stack requires sigaltstack()
|
|
||||||
and sigaction() SA_ONSTACK */
|
|
||||||
#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
|
|
||||||
# define FAULTHANDLER_USE_ALT_STACK
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(FAULTHANDLER_USE_ALT_STACK) && defined(HAVE_LINUX_AUXVEC_H) && defined(HAVE_SYS_AUXV_H)
|
#if defined(FAULTHANDLER_USE_ALT_STACK) && defined(HAVE_LINUX_AUXVEC_H) && defined(HAVE_SYS_AUXV_H)
|
||||||
# include <linux/auxvec.h> // AT_MINSIGSTKSZ
|
# include <linux/auxvec.h> // AT_MINSIGSTKSZ
|
||||||
# include <sys/auxv.h> // getauxval()
|
# include <sys/auxv.h> // getauxval()
|
||||||
|
@ -32,13 +26,6 @@
|
||||||
/* Allocate at maximum 100 MiB of the stack to raise the stack overflow */
|
/* Allocate at maximum 100 MiB of the stack to raise the stack overflow */
|
||||||
#define STACK_OVERFLOW_MAX_SIZE (100 * 1024 * 1024)
|
#define STACK_OVERFLOW_MAX_SIZE (100 * 1024 * 1024)
|
||||||
|
|
||||||
#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
|
|
||||||
|
|
||||||
#define PUTS(fd, str) _Py_write_noraise(fd, str, strlen(str))
|
#define PUTS(fd, str) _Py_write_noraise(fd, str, strlen(str))
|
||||||
|
|
||||||
|
|
||||||
|
@ -58,12 +45,6 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_SIGACTION
|
|
||||||
typedef struct sigaction _Py_sighandler_t;
|
|
||||||
#else
|
|
||||||
typedef PyOS_sighandler_t _Py_sighandler_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int signum;
|
int signum;
|
||||||
int enabled;
|
int enabled;
|
||||||
|
@ -72,47 +53,12 @@ typedef struct {
|
||||||
int all_threads;
|
int all_threads;
|
||||||
} fault_handler_t;
|
} fault_handler_t;
|
||||||
|
|
||||||
static struct {
|
#define fatal_error _PyRuntime.faulthandler.fatal_error
|
||||||
int enabled;
|
#define thread _PyRuntime.faulthandler.thread
|
||||||
PyObject *file;
|
|
||||||
int fd;
|
|
||||||
int all_threads;
|
|
||||||
PyInterpreterState *interp;
|
|
||||||
#ifdef MS_WINDOWS
|
|
||||||
void *exc_handler;
|
|
||||||
#endif
|
|
||||||
} fatal_error = {0, NULL, -1, 0};
|
|
||||||
|
|
||||||
static 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;
|
|
||||||
/* 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
|
#ifdef FAULTHANDLER_USER
|
||||||
typedef struct {
|
#define user_signals _PyRuntime.faulthandler.user_signals
|
||||||
int enabled;
|
typedef struct faulthandler_user_signal user_signal_t;
|
||||||
PyObject *file;
|
|
||||||
int fd;
|
|
||||||
int all_threads;
|
|
||||||
int chain;
|
|
||||||
_Py_sighandler_t previous;
|
|
||||||
PyInterpreterState *interp;
|
|
||||||
} user_signal_t;
|
|
||||||
|
|
||||||
static user_signal_t *user_signals;
|
|
||||||
|
|
||||||
static void faulthandler_user(int signum);
|
static void faulthandler_user(int signum);
|
||||||
#endif /* FAULTHANDLER_USER */
|
#endif /* FAULTHANDLER_USER */
|
||||||
|
|
||||||
|
@ -134,8 +80,8 @@ static const size_t faulthandler_nsignals = \
|
||||||
Py_ARRAY_LENGTH(faulthandler_handlers);
|
Py_ARRAY_LENGTH(faulthandler_handlers);
|
||||||
|
|
||||||
#ifdef FAULTHANDLER_USE_ALT_STACK
|
#ifdef FAULTHANDLER_USE_ALT_STACK
|
||||||
static stack_t stack;
|
# define stack _PyRuntime.faulthandler.stack
|
||||||
static stack_t old_stack;
|
# define old_stack _PyRuntime.faulthandler.old_stack
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -1094,7 +1040,7 @@ faulthandler_fatal_error_thread(void *plock)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
faulthandler_fatal_error_c_thread(PyObject *self, PyObject *args)
|
faulthandler_fatal_error_c_thread(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
long thread;
|
long tid;
|
||||||
PyThread_type_lock lock;
|
PyThread_type_lock lock;
|
||||||
|
|
||||||
faulthandler_suppress_crash_report();
|
faulthandler_suppress_crash_report();
|
||||||
|
@ -1105,8 +1051,8 @@ faulthandler_fatal_error_c_thread(PyObject *self, PyObject *args)
|
||||||
|
|
||||||
PyThread_acquire_lock(lock, WAIT_LOCK);
|
PyThread_acquire_lock(lock, WAIT_LOCK);
|
||||||
|
|
||||||
thread = PyThread_start_new_thread(faulthandler_fatal_error_thread, lock);
|
tid = PyThread_start_new_thread(faulthandler_fatal_error_thread, lock);
|
||||||
if (thread == -1) {
|
if (tid == -1) {
|
||||||
PyThread_free_lock(lock);
|
PyThread_free_lock(lock);
|
||||||
PyErr_SetString(PyExc_RuntimeError, "unable to start the thread");
|
PyErr_SetString(PyExc_RuntimeError, "unable to start the thread");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -214,6 +214,7 @@
|
||||||
<ClInclude Include="..\Include\internal\pycore_dict_state.h" />
|
<ClInclude Include="..\Include\internal\pycore_dict_state.h" />
|
||||||
<ClInclude Include="..\Include\internal\pycore_dtoa.h" />
|
<ClInclude Include="..\Include\internal\pycore_dtoa.h" />
|
||||||
<ClInclude Include="..\Include\internal\pycore_exceptions.h" />
|
<ClInclude Include="..\Include\internal\pycore_exceptions.h" />
|
||||||
|
<ClInclude Include="..\Include\internal\pycore_faulthandler.h" />
|
||||||
<ClInclude Include="..\Include\internal\pycore_fileutils.h" />
|
<ClInclude Include="..\Include\internal\pycore_fileutils.h" />
|
||||||
<ClInclude Include="..\Include\internal\pycore_floatobject.h" />
|
<ClInclude Include="..\Include\internal\pycore_floatobject.h" />
|
||||||
<ClInclude Include="..\Include\internal\pycore_format.h" />
|
<ClInclude Include="..\Include\internal\pycore_format.h" />
|
||||||
|
|
|
@ -549,6 +549,9 @@
|
||||||
<ClInclude Include="..\Include\internal\pycore_exceptions.h">
|
<ClInclude Include="..\Include\internal\pycore_exceptions.h">
|
||||||
<Filter>Include\internal</Filter>
|
<Filter>Include\internal</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\Include\internal\pycore_faulthandler.h">
|
||||||
|
<Filter>Include\internal</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="..\Include\internal\pycore_fileutils.h">
|
<ClInclude Include="..\Include\internal\pycore_fileutils.h">
|
||||||
<Filter>Include\internal</Filter>
|
<Filter>Include\internal</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
@ -558,6 +561,9 @@
|
||||||
<ClInclude Include="..\Include\internal\pycore_format.h">
|
<ClInclude Include="..\Include\internal\pycore_format.h">
|
||||||
<Filter>Include\internal</Filter>
|
<Filter>Include\internal</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\Include\internal\pycore_function.h">
|
||||||
|
<Filter>Include\internal</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="..\Include\internal\pycore_gc.h">
|
<ClInclude Include="..\Include\internal\pycore_gc.h">
|
||||||
<Filter>Include\internal</Filter>
|
<Filter>Include\internal</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
|
@ -361,15 +361,6 @@ Modules/itertoolsmodule.c - tee_type -
|
||||||
Modules/itertoolsmodule.c - teedataobject_type -
|
Modules/itertoolsmodule.c - teedataobject_type -
|
||||||
Modules/itertoolsmodule.c - ziplongest_type -
|
Modules/itertoolsmodule.c - ziplongest_type -
|
||||||
|
|
||||||
##-----------------------
|
|
||||||
## state
|
|
||||||
|
|
||||||
Modules/faulthandler.c - fatal_error -
|
|
||||||
Modules/faulthandler.c - thread -
|
|
||||||
Modules/faulthandler.c - user_signals -
|
|
||||||
Modules/faulthandler.c - stack -
|
|
||||||
Modules/faulthandler.c - old_stack -
|
|
||||||
|
|
||||||
|
|
||||||
##################################
|
##################################
|
||||||
## global non-objects to fix in builtin modules
|
## global non-objects to fix in builtin modules
|
||||||
|
@ -377,7 +368,6 @@ Modules/faulthandler.c - old_stack -
|
||||||
##-----------------------
|
##-----------------------
|
||||||
## state
|
## state
|
||||||
|
|
||||||
Modules/faulthandler.c faulthandler_dump_traceback reentrant -
|
|
||||||
Modules/signalmodule.c - is_tripped -
|
Modules/signalmodule.c - is_tripped -
|
||||||
Modules/signalmodule.c - signal_global_state -
|
Modules/signalmodule.c - signal_global_state -
|
||||||
Modules/signalmodule.c - wakeup -
|
Modules/signalmodule.c - wakeup -
|
||||||
|
|
Can't render this file because it has a wrong number of fields in line 4.
|
|
@ -151,6 +151,7 @@ Python/sysmodule.c - _preinit_xoptions -
|
||||||
|
|
||||||
# thread-safety
|
# thread-safety
|
||||||
# XXX need race protection?
|
# XXX need race protection?
|
||||||
|
Modules/faulthandler.c faulthandler_dump_traceback reentrant -
|
||||||
Python/pylifecycle.c _Py_FatalErrorFormat reentrant -
|
Python/pylifecycle.c _Py_FatalErrorFormat reentrant -
|
||||||
Python/pylifecycle.c fatal_error reentrant -
|
Python/pylifecycle.c fatal_error reentrant -
|
||||||
|
|
||||||
|
|
Can't render this file because it has a wrong number of fields in line 4.
|
Loading…
Reference in New Issue