_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(c_exception));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(c_parameter_type));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(c_return));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(c_stack));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(cached_datetime_module));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(cached_statements));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(cadata));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(category));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(cb_type));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(certfile));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(chain));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(check_same_thread));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(clear));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(close));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(excepthook));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(exception));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(existing_file_name));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(exit));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(exp));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(expression));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(extend));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(rel_tol));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(release));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(reload));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(repeat));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(repl));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(replace));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(reqrefs));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(shared));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(show_cmd));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(signed));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(signum));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(size));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(sizehint));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(skip_file_prefixes));
STRUCT_FOR_ID(c_exception)
STRUCT_FOR_ID(c_parameter_type)
STRUCT_FOR_ID(c_return)
+ STRUCT_FOR_ID(c_stack)
STRUCT_FOR_ID(cached_datetime_module)
STRUCT_FOR_ID(cached_statements)
STRUCT_FOR_ID(cadata)
STRUCT_FOR_ID(category)
STRUCT_FOR_ID(cb_type)
STRUCT_FOR_ID(certfile)
+ STRUCT_FOR_ID(chain)
STRUCT_FOR_ID(check_same_thread)
STRUCT_FOR_ID(clear)
STRUCT_FOR_ID(close)
STRUCT_FOR_ID(excepthook)
STRUCT_FOR_ID(exception)
STRUCT_FOR_ID(existing_file_name)
+ STRUCT_FOR_ID(exit)
STRUCT_FOR_ID(exp)
STRUCT_FOR_ID(expression)
STRUCT_FOR_ID(extend)
STRUCT_FOR_ID(rel_tol)
STRUCT_FOR_ID(release)
STRUCT_FOR_ID(reload)
+ STRUCT_FOR_ID(repeat)
STRUCT_FOR_ID(repl)
STRUCT_FOR_ID(replace)
STRUCT_FOR_ID(reqrefs)
STRUCT_FOR_ID(shared)
STRUCT_FOR_ID(show_cmd)
STRUCT_FOR_ID(signed)
+ STRUCT_FOR_ID(signum)
STRUCT_FOR_ID(size)
STRUCT_FOR_ID(sizehint)
STRUCT_FOR_ID(skip_file_prefixes)
INIT_ID(c_exception), \
INIT_ID(c_parameter_type), \
INIT_ID(c_return), \
+ INIT_ID(c_stack), \
INIT_ID(cached_datetime_module), \
INIT_ID(cached_statements), \
INIT_ID(cadata), \
INIT_ID(category), \
INIT_ID(cb_type), \
INIT_ID(certfile), \
+ INIT_ID(chain), \
INIT_ID(check_same_thread), \
INIT_ID(clear), \
INIT_ID(close), \
INIT_ID(excepthook), \
INIT_ID(exception), \
INIT_ID(existing_file_name), \
+ INIT_ID(exit), \
INIT_ID(exp), \
INIT_ID(expression), \
INIT_ID(extend), \
INIT_ID(rel_tol), \
INIT_ID(release), \
INIT_ID(reload), \
+ INIT_ID(repeat), \
INIT_ID(repl), \
INIT_ID(replace), \
INIT_ID(reqrefs), \
INIT_ID(shared), \
INIT_ID(show_cmd), \
INIT_ID(signed), \
+ INIT_ID(signum), \
INIT_ID(size), \
INIT_ID(sizehint), \
INIT_ID(skip_file_prefixes), \
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(c_stack);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(cached_datetime_module);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(chain);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(check_same_thread);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(exit);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(exp);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(repeat);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(repl);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(signum);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(size);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
'Segmentation fault',
all_threads=False)
+ @skip_segfault_on_android
+ def test_enable_without_c_stack(self):
+ self.check_fatal_error("""
+ import faulthandler
+ faulthandler.enable(c_stack=False)
+ faulthandler._sigsegv()
+ """,
+ 3,
+ 'Segmentation fault',
+ c_stack=False)
+
@skip_segfault_on_android
def test_disable(self):
code = """
--- /dev/null
+/*[clinic input]
+preserve
+[clinic start generated code]*/
+
+#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+# include "pycore_gc.h" // PyGC_Head
+# include "pycore_runtime.h" // _Py_ID()
+#endif
+#include "pycore_long.h" // _PyLong_UnsignedInt_Converter()
+#include "pycore_modsupport.h" // _PyArg_UnpackKeywords()
+
+PyDoc_STRVAR(faulthandler_dump_traceback_py__doc__,
+"dump_traceback($module, /, file=sys.stderr, all_threads=True)\n"
+"--\n"
+"\n"
+"Dump the traceback of the current thread into file.\n"
+"\n"
+"Dump the traceback of all threads if all_threads is true.");
+
+#define FAULTHANDLER_DUMP_TRACEBACK_PY_METHODDEF \
+ {"dump_traceback", _PyCFunction_CAST(faulthandler_dump_traceback_py), METH_FASTCALL|METH_KEYWORDS, faulthandler_dump_traceback_py__doc__},
+
+static PyObject *
+faulthandler_dump_traceback_py_impl(PyObject *module, PyObject *file,
+ int all_threads);
+
+static PyObject *
+faulthandler_dump_traceback_py(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+ PyObject *return_value = NULL;
+ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+ #define NUM_KEYWORDS 2
+ static struct {
+ PyGC_Head _this_is_not_used;
+ PyObject_VAR_HEAD
+ Py_hash_t ob_hash;
+ PyObject *ob_item[NUM_KEYWORDS];
+ } _kwtuple = {
+ .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+ .ob_hash = -1,
+ .ob_item = { &_Py_ID(file), &_Py_ID(all_threads), },
+ };
+ #undef NUM_KEYWORDS
+ #define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+ #else // !Py_BUILD_CORE
+ # define KWTUPLE NULL
+ #endif // !Py_BUILD_CORE
+
+ static const char * const _keywords[] = {"file", "all_threads", NULL};
+ static _PyArg_Parser _parser = {
+ .keywords = _keywords,
+ .fname = "dump_traceback",
+ .kwtuple = KWTUPLE,
+ };
+ #undef KWTUPLE
+ PyObject *argsbuf[2];
+ Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
+ PyObject *file = NULL;
+ int all_threads = 1;
+
+ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+ /*minpos*/ 0, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+ if (!args) {
+ goto exit;
+ }
+ if (!noptargs) {
+ goto skip_optional_pos;
+ }
+ if (args[0]) {
+ file = args[0];
+ if (!--noptargs) {
+ goto skip_optional_pos;
+ }
+ }
+ all_threads = PyObject_IsTrue(args[1]);
+ if (all_threads < 0) {
+ goto exit;
+ }
+skip_optional_pos:
+ return_value = faulthandler_dump_traceback_py_impl(module, file, all_threads);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(faulthandler_dump_c_stack_py__doc__,
+"dump_c_stack($module, /, file=sys.stderr)\n"
+"--\n"
+"\n"
+"Dump the C stack of the current thread.");
+
+#define FAULTHANDLER_DUMP_C_STACK_PY_METHODDEF \
+ {"dump_c_stack", _PyCFunction_CAST(faulthandler_dump_c_stack_py), METH_FASTCALL|METH_KEYWORDS, faulthandler_dump_c_stack_py__doc__},
+
+static PyObject *
+faulthandler_dump_c_stack_py_impl(PyObject *module, PyObject *file);
+
+static PyObject *
+faulthandler_dump_c_stack_py(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+ PyObject *return_value = NULL;
+ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+ #define NUM_KEYWORDS 1
+ static struct {
+ PyGC_Head _this_is_not_used;
+ PyObject_VAR_HEAD
+ Py_hash_t ob_hash;
+ PyObject *ob_item[NUM_KEYWORDS];
+ } _kwtuple = {
+ .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+ .ob_hash = -1,
+ .ob_item = { &_Py_ID(file), },
+ };
+ #undef NUM_KEYWORDS
+ #define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+ #else // !Py_BUILD_CORE
+ # define KWTUPLE NULL
+ #endif // !Py_BUILD_CORE
+
+ static const char * const _keywords[] = {"file", NULL};
+ static _PyArg_Parser _parser = {
+ .keywords = _keywords,
+ .fname = "dump_c_stack",
+ .kwtuple = KWTUPLE,
+ };
+ #undef KWTUPLE
+ PyObject *argsbuf[1];
+ Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
+ PyObject *file = NULL;
+
+ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+ /*minpos*/ 0, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+ if (!args) {
+ goto exit;
+ }
+ if (!noptargs) {
+ goto skip_optional_pos;
+ }
+ file = args[0];
+skip_optional_pos:
+ return_value = faulthandler_dump_c_stack_py_impl(module, file);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(faulthandler_py_enable__doc__,
+"enable($module, /, file=sys.stderr, all_threads=True, c_stack=True)\n"
+"--\n"
+"\n"
+"Enable the fault handler.");
+
+#define FAULTHANDLER_PY_ENABLE_METHODDEF \
+ {"enable", _PyCFunction_CAST(faulthandler_py_enable), METH_FASTCALL|METH_KEYWORDS, faulthandler_py_enable__doc__},
+
+static PyObject *
+faulthandler_py_enable_impl(PyObject *module, PyObject *file,
+ int all_threads, int c_stack);
+
+static PyObject *
+faulthandler_py_enable(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+ PyObject *return_value = NULL;
+ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+ #define NUM_KEYWORDS 3
+ static struct {
+ PyGC_Head _this_is_not_used;
+ PyObject_VAR_HEAD
+ Py_hash_t ob_hash;
+ PyObject *ob_item[NUM_KEYWORDS];
+ } _kwtuple = {
+ .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+ .ob_hash = -1,
+ .ob_item = { &_Py_ID(file), &_Py_ID(all_threads), &_Py_ID(c_stack), },
+ };
+ #undef NUM_KEYWORDS
+ #define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+ #else // !Py_BUILD_CORE
+ # define KWTUPLE NULL
+ #endif // !Py_BUILD_CORE
+
+ static const char * const _keywords[] = {"file", "all_threads", "c_stack", NULL};
+ static _PyArg_Parser _parser = {
+ .keywords = _keywords,
+ .fname = "enable",
+ .kwtuple = KWTUPLE,
+ };
+ #undef KWTUPLE
+ PyObject *argsbuf[3];
+ Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
+ PyObject *file = NULL;
+ int all_threads = 1;
+ int c_stack = 1;
+
+ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+ /*minpos*/ 0, /*maxpos*/ 3, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+ if (!args) {
+ goto exit;
+ }
+ if (!noptargs) {
+ goto skip_optional_pos;
+ }
+ if (args[0]) {
+ file = args[0];
+ if (!--noptargs) {
+ goto skip_optional_pos;
+ }
+ }
+ if (args[1]) {
+ all_threads = PyObject_IsTrue(args[1]);
+ if (all_threads < 0) {
+ goto exit;
+ }
+ if (!--noptargs) {
+ goto skip_optional_pos;
+ }
+ }
+ c_stack = PyObject_IsTrue(args[2]);
+ if (c_stack < 0) {
+ goto exit;
+ }
+skip_optional_pos:
+ return_value = faulthandler_py_enable_impl(module, file, all_threads, c_stack);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(faulthandler_disable_py__doc__,
+"disable($module, /)\n"
+"--\n"
+"\n"
+"Disable the fault handler.");
+
+#define FAULTHANDLER_DISABLE_PY_METHODDEF \
+ {"disable", (PyCFunction)faulthandler_disable_py, METH_NOARGS, faulthandler_disable_py__doc__},
+
+static PyObject *
+faulthandler_disable_py_impl(PyObject *module);
+
+static PyObject *
+faulthandler_disable_py(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+ return faulthandler_disable_py_impl(module);
+}
+
+PyDoc_STRVAR(faulthandler_is_enabled__doc__,
+"is_enabled($module, /)\n"
+"--\n"
+"\n"
+"Check if the handler is enabled.");
+
+#define FAULTHANDLER_IS_ENABLED_METHODDEF \
+ {"is_enabled", (PyCFunction)faulthandler_is_enabled, METH_NOARGS, faulthandler_is_enabled__doc__},
+
+static int
+faulthandler_is_enabled_impl(PyObject *module);
+
+static PyObject *
+faulthandler_is_enabled(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+ PyObject *return_value = NULL;
+ int _return_value;
+
+ _return_value = faulthandler_is_enabled_impl(module);
+ if ((_return_value == -1) && PyErr_Occurred()) {
+ goto exit;
+ }
+ return_value = PyBool_FromLong((long)_return_value);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(faulthandler_dump_traceback_later__doc__,
+"dump_traceback_later($module, /, timeout, repeat=False,\n"
+" file=sys.stderr, exit=False)\n"
+"--\n"
+"\n"
+"Dump the traceback of all threads in timeout seconds.\n"
+"\n"
+"If repeat is true, the tracebacks of all threads are dumped every timeout\n"
+"seconds. If exit is true, call _exit(1) which is not safe.");
+
+#define FAULTHANDLER_DUMP_TRACEBACK_LATER_METHODDEF \
+ {"dump_traceback_later", _PyCFunction_CAST(faulthandler_dump_traceback_later), METH_FASTCALL|METH_KEYWORDS, faulthandler_dump_traceback_later__doc__},
+
+static PyObject *
+faulthandler_dump_traceback_later_impl(PyObject *module,
+ PyObject *timeout_obj, int repeat,
+ PyObject *file, int exit);
+
+static PyObject *
+faulthandler_dump_traceback_later(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+ PyObject *return_value = NULL;
+ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+ #define NUM_KEYWORDS 4
+ static struct {
+ PyGC_Head _this_is_not_used;
+ PyObject_VAR_HEAD
+ Py_hash_t ob_hash;
+ PyObject *ob_item[NUM_KEYWORDS];
+ } _kwtuple = {
+ .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+ .ob_hash = -1,
+ .ob_item = { &_Py_ID(timeout), &_Py_ID(repeat), &_Py_ID(file), &_Py_ID(exit), },
+ };
+ #undef NUM_KEYWORDS
+ #define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+ #else // !Py_BUILD_CORE
+ # define KWTUPLE NULL
+ #endif // !Py_BUILD_CORE
+
+ static const char * const _keywords[] = {"timeout", "repeat", "file", "exit", NULL};
+ static _PyArg_Parser _parser = {
+ .keywords = _keywords,
+ .fname = "dump_traceback_later",
+ .kwtuple = KWTUPLE,
+ };
+ #undef KWTUPLE
+ PyObject *argsbuf[4];
+ Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
+ PyObject *timeout_obj;
+ int repeat = 0;
+ PyObject *file = NULL;
+ int exit = 0;
+
+ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+ /*minpos*/ 1, /*maxpos*/ 4, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+ if (!args) {
+ goto exit;
+ }
+ timeout_obj = args[0];
+ if (!noptargs) {
+ goto skip_optional_pos;
+ }
+ if (args[1]) {
+ repeat = PyObject_IsTrue(args[1]);
+ if (repeat < 0) {
+ goto exit;
+ }
+ if (!--noptargs) {
+ goto skip_optional_pos;
+ }
+ }
+ if (args[2]) {
+ file = args[2];
+ if (!--noptargs) {
+ goto skip_optional_pos;
+ }
+ }
+ exit = PyObject_IsTrue(args[3]);
+ if (exit < 0) {
+ goto exit;
+ }
+skip_optional_pos:
+ return_value = faulthandler_dump_traceback_later_impl(module, timeout_obj, repeat, file, exit);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(faulthandler_cancel_dump_traceback_later_py__doc__,
+"cancel_dump_traceback_later($module, /)\n"
+"--\n"
+"\n"
+"Cancel the previous call to dump_traceback_later().");
+
+#define FAULTHANDLER_CANCEL_DUMP_TRACEBACK_LATER_PY_METHODDEF \
+ {"cancel_dump_traceback_later", (PyCFunction)faulthandler_cancel_dump_traceback_later_py, METH_NOARGS, faulthandler_cancel_dump_traceback_later_py__doc__},
+
+static PyObject *
+faulthandler_cancel_dump_traceback_later_py_impl(PyObject *module);
+
+static PyObject *
+faulthandler_cancel_dump_traceback_later_py(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+ return faulthandler_cancel_dump_traceback_later_py_impl(module);
+}
+
+#if defined(FAULTHANDLER_USER)
+
+PyDoc_STRVAR(faulthandler_register_py__doc__,
+"register($module, /, signum, file=sys.stderr, all_threads=True,\n"
+" chain=False)\n"
+"--\n"
+"\n"
+"Register a handler for the signal \'signum\'.\n"
+"\n"
+"Dump the traceback of the current thread, or of all threads if\n"
+"all_threads is True, into file.");
+
+#define FAULTHANDLER_REGISTER_PY_METHODDEF \
+ {"register", _PyCFunction_CAST(faulthandler_register_py), METH_FASTCALL|METH_KEYWORDS, faulthandler_register_py__doc__},
+
+static PyObject *
+faulthandler_register_py_impl(PyObject *module, int signum, PyObject *file,
+ int all_threads, int chain);
+
+static PyObject *
+faulthandler_register_py(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+ PyObject *return_value = NULL;
+ #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+ #define NUM_KEYWORDS 4
+ static struct {
+ PyGC_Head _this_is_not_used;
+ PyObject_VAR_HEAD
+ Py_hash_t ob_hash;
+ PyObject *ob_item[NUM_KEYWORDS];
+ } _kwtuple = {
+ .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+ .ob_hash = -1,
+ .ob_item = { &_Py_ID(signum), &_Py_ID(file), &_Py_ID(all_threads), &_Py_ID(chain), },
+ };
+ #undef NUM_KEYWORDS
+ #define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+ #else // !Py_BUILD_CORE
+ # define KWTUPLE NULL
+ #endif // !Py_BUILD_CORE
+
+ static const char * const _keywords[] = {"signum", "file", "all_threads", "chain", NULL};
+ static _PyArg_Parser _parser = {
+ .keywords = _keywords,
+ .fname = "register",
+ .kwtuple = KWTUPLE,
+ };
+ #undef KWTUPLE
+ PyObject *argsbuf[4];
+ Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
+ int signum;
+ PyObject *file = NULL;
+ int all_threads = 1;
+ int chain = 0;
+
+ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+ /*minpos*/ 1, /*maxpos*/ 4, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+ if (!args) {
+ goto exit;
+ }
+ signum = PyLong_AsInt(args[0]);
+ if (signum == -1 && PyErr_Occurred()) {
+ goto exit;
+ }
+ if (!noptargs) {
+ goto skip_optional_pos;
+ }
+ if (args[1]) {
+ file = args[1];
+ if (!--noptargs) {
+ goto skip_optional_pos;
+ }
+ }
+ if (args[2]) {
+ all_threads = PyObject_IsTrue(args[2]);
+ if (all_threads < 0) {
+ goto exit;
+ }
+ if (!--noptargs) {
+ goto skip_optional_pos;
+ }
+ }
+ chain = PyObject_IsTrue(args[3]);
+ if (chain < 0) {
+ goto exit;
+ }
+skip_optional_pos:
+ return_value = faulthandler_register_py_impl(module, signum, file, all_threads, chain);
+
+exit:
+ return return_value;
+}
+
+#endif /* defined(FAULTHANDLER_USER) */
+
+#if defined(FAULTHANDLER_USER)
+
+PyDoc_STRVAR(faulthandler_unregister_py__doc__,
+"unregister($module, signum, /)\n"
+"--\n"
+"\n"
+"Unregister the handler of the signal \'signum\' registered by register().");
+
+#define FAULTHANDLER_UNREGISTER_PY_METHODDEF \
+ {"unregister", (PyCFunction)faulthandler_unregister_py, METH_O, faulthandler_unregister_py__doc__},
+
+static PyObject *
+faulthandler_unregister_py_impl(PyObject *module, int signum);
+
+static PyObject *
+faulthandler_unregister_py(PyObject *module, PyObject *arg)
+{
+ PyObject *return_value = NULL;
+ int signum;
+
+ signum = PyLong_AsInt(arg);
+ if (signum == -1 && PyErr_Occurred()) {
+ goto exit;
+ }
+ return_value = faulthandler_unregister_py_impl(module, signum);
+
+exit:
+ return return_value;
+}
+
+#endif /* defined(FAULTHANDLER_USER) */
+
+PyDoc_STRVAR(faulthandler__sigsegv__doc__,
+"_sigsegv($module, release_gil=False, /)\n"
+"--\n"
+"\n"
+"Raise a SIGSEGV signal.");
+
+#define FAULTHANDLER__SIGSEGV_METHODDEF \
+ {"_sigsegv", _PyCFunction_CAST(faulthandler__sigsegv), METH_FASTCALL, faulthandler__sigsegv__doc__},
+
+static PyObject *
+faulthandler__sigsegv_impl(PyObject *module, int release_gil);
+
+static PyObject *
+faulthandler__sigsegv(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+ PyObject *return_value = NULL;
+ int release_gil = 0;
+
+ if (!_PyArg_CheckPositional("_sigsegv", nargs, 0, 1)) {
+ goto exit;
+ }
+ if (nargs < 1) {
+ goto skip_optional;
+ }
+ release_gil = PyObject_IsTrue(args[0]);
+ if (release_gil < 0) {
+ goto exit;
+ }
+skip_optional:
+ return_value = faulthandler__sigsegv_impl(module, release_gil);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(faulthandler__fatal_error_c_thread__doc__,
+"_fatal_error_c_thread($module, /)\n"
+"--\n"
+"\n"
+"Call Py_FatalError() in a new C thread.");
+
+#define FAULTHANDLER__FATAL_ERROR_C_THREAD_METHODDEF \
+ {"_fatal_error_c_thread", (PyCFunction)faulthandler__fatal_error_c_thread, METH_NOARGS, faulthandler__fatal_error_c_thread__doc__},
+
+static PyObject *
+faulthandler__fatal_error_c_thread_impl(PyObject *module);
+
+static PyObject *
+faulthandler__fatal_error_c_thread(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+ return faulthandler__fatal_error_c_thread_impl(module);
+}
+
+PyDoc_STRVAR(faulthandler__sigfpe__doc__,
+"_sigfpe($module, /)\n"
+"--\n"
+"\n"
+"Raise a SIGFPE signal.");
+
+#define FAULTHANDLER__SIGFPE_METHODDEF \
+ {"_sigfpe", (PyCFunction)faulthandler__sigfpe, METH_NOARGS, faulthandler__sigfpe__doc__},
+
+static PyObject *
+faulthandler__sigfpe_impl(PyObject *module);
+
+static PyObject *
+faulthandler__sigfpe(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+ return faulthandler__sigfpe_impl(module);
+}
+
+PyDoc_STRVAR(faulthandler__sigabrt__doc__,
+"_sigabrt($module, /)\n"
+"--\n"
+"\n"
+"Raise a SIGABRT signal.");
+
+#define FAULTHANDLER__SIGABRT_METHODDEF \
+ {"_sigabrt", (PyCFunction)faulthandler__sigabrt, METH_NOARGS, faulthandler__sigabrt__doc__},
+
+static PyObject *
+faulthandler__sigabrt_impl(PyObject *module);
+
+static PyObject *
+faulthandler__sigabrt(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+ return faulthandler__sigabrt_impl(module);
+}
+
+#if defined(FAULTHANDLER_USE_ALT_STACK)
+
+PyDoc_STRVAR(faulthandler__stack_overflow__doc__,
+"_stack_overflow($module, /)\n"
+"--\n"
+"\n"
+"Recursive call to raise a stack overflow.");
+
+#define FAULTHANDLER__STACK_OVERFLOW_METHODDEF \
+ {"_stack_overflow", (PyCFunction)faulthandler__stack_overflow, METH_NOARGS, faulthandler__stack_overflow__doc__},
+
+static PyObject *
+faulthandler__stack_overflow_impl(PyObject *module);
+
+static PyObject *
+faulthandler__stack_overflow(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+ return faulthandler__stack_overflow_impl(module);
+}
+
+#endif /* defined(FAULTHANDLER_USE_ALT_STACK) */
+
+#if defined(MS_WINDOWS)
+
+PyDoc_STRVAR(faulthandler__raise_exception__doc__,
+"_raise_exception($module, code, flags=0, /)\n"
+"--\n"
+"\n"
+"Call RaiseException(code, flags).");
+
+#define FAULTHANDLER__RAISE_EXCEPTION_METHODDEF \
+ {"_raise_exception", _PyCFunction_CAST(faulthandler__raise_exception), METH_FASTCALL, faulthandler__raise_exception__doc__},
+
+static PyObject *
+faulthandler__raise_exception_impl(PyObject *module, unsigned int code,
+ unsigned int flags);
+
+static PyObject *
+faulthandler__raise_exception(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+ PyObject *return_value = NULL;
+ unsigned int code;
+ unsigned int flags = 0;
+
+ if (!_PyArg_CheckPositional("_raise_exception", nargs, 1, 2)) {
+ goto exit;
+ }
+ if (!_PyLong_UnsignedInt_Converter(args[0], &code)) {
+ goto exit;
+ }
+ if (nargs < 2) {
+ goto skip_optional;
+ }
+ if (!_PyLong_UnsignedInt_Converter(args[1], &flags)) {
+ goto exit;
+ }
+skip_optional:
+ return_value = faulthandler__raise_exception_impl(module, code, flags);
+
+exit:
+ return return_value;
+}
+
+#endif /* defined(MS_WINDOWS) */
+
+#ifndef FAULTHANDLER_REGISTER_PY_METHODDEF
+ #define FAULTHANDLER_REGISTER_PY_METHODDEF
+#endif /* !defined(FAULTHANDLER_REGISTER_PY_METHODDEF) */
+
+#ifndef FAULTHANDLER_UNREGISTER_PY_METHODDEF
+ #define FAULTHANDLER_UNREGISTER_PY_METHODDEF
+#endif /* !defined(FAULTHANDLER_UNREGISTER_PY_METHODDEF) */
+
+#ifndef FAULTHANDLER__STACK_OVERFLOW_METHODDEF
+ #define FAULTHANDLER__STACK_OVERFLOW_METHODDEF
+#endif /* !defined(FAULTHANDLER__STACK_OVERFLOW_METHODDEF) */
+
+#ifndef FAULTHANDLER__RAISE_EXCEPTION_METHODDEF
+ #define FAULTHANDLER__RAISE_EXCEPTION_METHODDEF
+#endif /* !defined(FAULTHANDLER__RAISE_EXCEPTION_METHODDEF) */
+/*[clinic end generated code: output=31bf0149d0d02ccf input=a9049054013a1b77]*/
#endif
+#include "clinic/faulthandler.c.h"
+
+
/* Sentinel to ignore all_threads on free-threading */
#define FT_IGNORE_ALL_THREADS 2
#define PUTS(fd, str) (void)_Py_write_noraise(fd, str, strlen(str))
+/*[clinic input]
+module faulthandler
+[clinic start generated code]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=c3d4f47c4f3d440f]*/
+
+
typedef struct {
int signum;
int enabled;
reentrant = 0;
}
-static PyObject*
-faulthandler_dump_traceback_py(PyObject *self,
- PyObject *args, PyObject *kwargs)
+
+/*[clinic input]
+faulthandler.dump_traceback as faulthandler_dump_traceback_py
+
+ file: object(py_default="sys.stderr") = NULL
+ all_threads: bool = True
+
+Dump the traceback of the current thread into file.
+
+Dump the traceback of all threads if all_threads is true.
+[clinic start generated code]*/
+
+static PyObject *
+faulthandler_dump_traceback_py_impl(PyObject *module, PyObject *file,
+ int all_threads)
+/*[clinic end generated code: output=34efece0ca18314f input=b832ec55e27a7898]*/
{
- static char *kwlist[] = {"file", "all_threads", NULL};
- PyObject *file = NULL;
- int all_threads = 1;
PyThreadState *tstate;
const char *errmsg;
int fd;
- if (!PyArg_ParseTupleAndKeywords(args, kwargs,
- "|Op:dump_traceback", kwlist,
- &file, &all_threads))
- return NULL;
-
fd = faulthandler_get_fileno(&file);
if (fd < 0)
return NULL;
Py_RETURN_NONE;
}
-static PyObject *
-faulthandler_dump_c_stack_py(PyObject *self,
- PyObject *args, PyObject *kwargs)
-{
- static char *kwlist[] = {"file", NULL};
- PyObject *file = NULL;
- if (!PyArg_ParseTupleAndKeywords(args, kwargs,
- "|O:dump_c_stack", kwlist,
- &file)) {
- return NULL;
- }
+/*[clinic input]
+faulthandler.dump_c_stack as faulthandler_dump_c_stack_py
+
+ file: object(py_default="sys.stderr") = NULL
+Dump the C stack of the current thread.
+[clinic start generated code]*/
+
+static PyObject *
+faulthandler_dump_c_stack_py_impl(PyObject *module, PyObject *file)
+/*[clinic end generated code: output=151d6c95e9f8c0f6 input=10f6b6f29b635109]*/
+{
int fd = faulthandler_get_fileno(&file);
if (fd < 0) {
return NULL;
return 0;
}
-static PyObject*
-faulthandler_py_enable(PyObject *self, PyObject *args, PyObject *kwargs)
+
+/*[clinic input]
+faulthandler.enable as faulthandler_py_enable
+
+ file: object(py_default="sys.stderr") = NULL
+ all_threads: bool = True
+ c_stack: bool = True
+
+Enable the fault handler.
+[clinic start generated code]*/
+
+static PyObject *
+faulthandler_py_enable_impl(PyObject *module, PyObject *file,
+ int all_threads, int c_stack)
+/*[clinic end generated code: output=580d89b5eb62f1cb input=77277746a88b25ca]*/
{
- static char *kwlist[] = {"file", "all_threads", "c_stack", NULL};
- PyObject *file = NULL;
- int all_threads = 1;
int fd;
- int c_stack = 1;
PyThreadState *tstate;
- if (!PyArg_ParseTupleAndKeywords(args, kwargs,
- "|Opp:enable", kwlist, &file, &all_threads, &c_stack))
- return NULL;
-
fd = faulthandler_get_fileno(&file);
if (fd < 0)
return NULL;
Py_CLEAR(fatal_error.file);
}
-static PyObject*
-faulthandler_disable_py(PyObject *self, PyObject *Py_UNUSED(ignored))
+
+/*[clinic input]
+faulthandler.disable as faulthandler_disable_py
+
+Disable the fault handler.
+[clinic start generated code]*/
+
+static PyObject *
+faulthandler_disable_py_impl(PyObject *module)
+/*[clinic end generated code: output=e9087a04535af3cb input=6223eac6804550af]*/
{
if (!fatal_error.enabled) {
Py_RETURN_FALSE;
Py_RETURN_TRUE;
}
-static PyObject*
-faulthandler_is_enabled(PyObject *self, PyObject *Py_UNUSED(ignored))
+
+/*[clinic input]
+faulthandler.is_enabled -> bool
+
+Check if the handler is enabled.
+[clinic start generated code]*/
+
+static int
+faulthandler_is_enabled_impl(PyObject *module)
+/*[clinic end generated code: output=b9f33a3e0f881a23 input=3d5532547eb14bf9]*/
{
- return PyBool_FromLong(fatal_error.enabled);
+ return fatal_error.enabled;
}
static void
return _PyMem_Strdup(buffer);
}
-static PyObject*
-faulthandler_dump_traceback_later(PyObject *self,
- PyObject *args, PyObject *kwargs)
+
+/*[clinic input]
+faulthandler.dump_traceback_later
+
+ timeout as timeout_obj: object
+ repeat: bool = False
+ file: object(py_default="sys.stderr") = NULL
+ exit: bool = False
+
+Dump the traceback of all threads in timeout seconds.
+
+If repeat is true, the tracebacks of all threads are dumped every timeout
+seconds. If exit is true, call _exit(1) which is not safe.
+[clinic start generated code]*/
+
+static PyObject *
+faulthandler_dump_traceback_later_impl(PyObject *module,
+ PyObject *timeout_obj, int repeat,
+ PyObject *file, int exit)
+/*[clinic end generated code: output=a24d80d694d25ba2 input=fd005625ecc2ba9a]*/
{
- static char *kwlist[] = {"timeout", "repeat", "file", "exit", NULL};
- PyObject *timeout_obj;
PyTime_t timeout, timeout_us;
- int repeat = 0;
- PyObject *file = NULL;
int fd;
- int exit = 0;
PyThreadState *tstate;
char *header;
size_t header_len;
- if (!PyArg_ParseTupleAndKeywords(args, kwargs,
- "O|iOi:dump_traceback_later", kwlist,
- &timeout_obj, &repeat, &file, &exit))
- return NULL;
-
if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
_PyTime_ROUND_TIMEOUT) < 0) {
return NULL;
Py_RETURN_NONE;
}
-static PyObject*
-faulthandler_cancel_dump_traceback_later_py(PyObject *self,
- PyObject *Py_UNUSED(ignored))
+
+/*[clinic input]
+faulthandler.cancel_dump_traceback_later as faulthandler_cancel_dump_traceback_later_py
+
+Cancel the previous call to dump_traceback_later().
+[clinic start generated code]*/
+
+static PyObject *
+faulthandler_cancel_dump_traceback_later_py_impl(PyObject *module)
+/*[clinic end generated code: output=2cf303015d39c926 input=51ad64b6ca8412a4]*/
{
cancel_dump_traceback_later();
Py_RETURN_NONE;
return 1;
}
-static PyObject*
-faulthandler_register_py(PyObject *self,
- PyObject *args, PyObject *kwargs)
+
+/*[clinic input]
+faulthandler.register as faulthandler_register_py
+
+ signum: int
+ file: object(py_default="sys.stderr") = NULL
+ all_threads: bool = True
+ chain: bool = False
+
+Register a handler for the signal 'signum'.
+
+Dump the traceback of the current thread, or of all threads if
+all_threads is True, into file.
+[clinic start generated code]*/
+
+static PyObject *
+faulthandler_register_py_impl(PyObject *module, int signum, PyObject *file,
+ int all_threads, int chain)
+/*[clinic end generated code: output=1f770cee150a56cd input=ae9de829e850907b]*/
{
- static char *kwlist[] = {"signum", "file", "all_threads", "chain", NULL};
- int signum;
- PyObject *file = NULL;
- int all_threads = 1;
- int chain = 0;
int fd;
user_signal_t *user;
_Py_sighandler_t previous;
PyThreadState *tstate;
int err;
- if (!PyArg_ParseTupleAndKeywords(args, kwargs,
- "i|Opp:register", kwlist,
- &signum, &file, &all_threads, &chain))
- return NULL;
-
if (!check_signum(signum))
return NULL;
return 1;
}
-static PyObject*
-faulthandler_unregister_py(PyObject *self, PyObject *args)
+
+/*[clinic input]
+faulthandler.unregister as faulthandler_unregister_py
+
+ signum: int
+ /
+
+Unregister the handler of the signal 'signum' registered by register().
+[clinic start generated code]*/
+
+static PyObject *
+faulthandler_unregister_py_impl(PyObject *module, int signum)
+/*[clinic end generated code: output=01734423da1155ed input=c016de014495d384]*/
{
- int signum;
user_signal_t *user;
int change;
- if (!PyArg_ParseTuple(args, "i:unregister", &signum))
- return NULL;
-
if (!check_signum(signum))
return NULL;
#endif
}
+
+/*[clinic input]
+faulthandler._sigsegv
+
+ release_gil: bool = False
+ /
+
+Raise a SIGSEGV signal.
+[clinic start generated code]*/
+
static PyObject *
-faulthandler_sigsegv(PyObject *self, PyObject *args)
+faulthandler__sigsegv_impl(PyObject *module, int release_gil)
+/*[clinic end generated code: output=96e5a2f215b01b76 input=c6ad893cf2ea2b41]*/
{
- int release_gil = 0;
- if (!PyArg_ParseTuple(args, "|i:_sigsegv", &release_gil))
- return NULL;
-
if (release_gil) {
Py_BEGIN_ALLOW_THREADS
faulthandler_raise_sigsegv();
Py_FatalError("in new thread");
}
+
+/*[clinic input]
+faulthandler._fatal_error_c_thread
+
+Call Py_FatalError() in a new C thread.
+[clinic start generated code]*/
+
static PyObject *
-faulthandler_fatal_error_c_thread(PyObject *self, PyObject *args)
+faulthandler__fatal_error_c_thread_impl(PyObject *module)
+/*[clinic end generated code: output=101bc8aaf4a5eec1 input=fbdca6fffd639a39]*/
{
long tid;
PyThread_type_lock lock;
Py_RETURN_NONE;
}
-static PyObject*
-faulthandler_sigfpe(PyObject *self, PyObject *Py_UNUSED(dummy))
+
+/*[clinic input]
+faulthandler._sigfpe
+
+Raise a SIGFPE signal.
+[clinic start generated code]*/
+
+static PyObject *
+faulthandler__sigfpe_impl(PyObject *module)
+/*[clinic end generated code: output=dec9c98100e986db input=fd608a92d4421d28]*/
{
faulthandler_suppress_crash_report();
raise(SIGFPE);
Py_UNREACHABLE();
}
+
+/*[clinic input]
+faulthandler._sigabrt
+
+Raise a SIGABRT signal.
+[clinic start generated code]*/
+
static PyObject *
-faulthandler_sigabrt(PyObject *self, PyObject *args)
+faulthandler__sigabrt_impl(PyObject *module)
+/*[clinic end generated code: output=58c1378a0c166682 input=be3e0ecefb8676b8]*/
{
faulthandler_suppress_crash_report();
abort();
return stack_overflow(min_sp, max_sp, depth);
}
+
+/*[clinic input]
+faulthandler._stack_overflow
+
+Recursive call to raise a stack overflow.
+[clinic start generated code]*/
+
static PyObject *
-faulthandler_stack_overflow(PyObject *self, PyObject *Py_UNUSED(ignored))
+faulthandler__stack_overflow_impl(PyObject *module)
+/*[clinic end generated code: output=efffba4be522d8fb input=4291594a790b6c35]*/
{
size_t depth, size;
uintptr_t sp = (uintptr_t)&depth;
return 0;
}
+
#ifdef MS_WINDOWS
+/*[clinic input]
+faulthandler._raise_exception
+
+ code: unsigned_int
+ flags: unsigned_int = 0
+ /
+
+Call RaiseException(code, flags).
+[clinic start generated code]*/
+
static PyObject *
-faulthandler_raise_exception(PyObject *self, PyObject *args)
+faulthandler__raise_exception_impl(PyObject *module, unsigned int code,
+ unsigned int flags)
+/*[clinic end generated code: output=2346cf318eab10dc input=43a5ba0eb7794504]*/
{
- 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;
"faulthandler module.");
static PyMethodDef module_methods[] = {
- {"enable",
- _PyCFunction_CAST(faulthandler_py_enable), METH_VARARGS|METH_KEYWORDS,
- PyDoc_STR("enable($module, /, file=sys.stderr, all_threads=True)\n--\n\n"
- "Enable the fault handler.")},
- {"disable", faulthandler_disable_py, METH_NOARGS,
- PyDoc_STR("disable($module, /)\n--\n\n"
- "Disable the fault handler.")},
- {"is_enabled", faulthandler_is_enabled, METH_NOARGS,
- PyDoc_STR("is_enabled($module, /)\n--\n\n"
- "Check if the handler is enabled.")},
- {"dump_traceback",
- _PyCFunction_CAST(faulthandler_dump_traceback_py), METH_VARARGS|METH_KEYWORDS,
- PyDoc_STR("dump_traceback($module, /, file=sys.stderr, all_threads=True)\n--\n\n"
- "Dump the traceback of the current thread, or of all threads "
- "if all_threads is True, into file.")},
- {"dump_c_stack",
- _PyCFunction_CAST(faulthandler_dump_c_stack_py), METH_VARARGS|METH_KEYWORDS,
- PyDoc_STR("dump_c_stack($module, /, file=sys.stderr)\n--\n\n"
- "Dump the C stack of the current thread.")},
- {"dump_traceback_later",
- _PyCFunction_CAST(faulthandler_dump_traceback_later), METH_VARARGS|METH_KEYWORDS,
- PyDoc_STR("dump_traceback_later($module, /, timeout, repeat=False, file=sys.stderr, exit=False)\n--\n\n"
- "Dump the traceback of all threads in timeout seconds,\n"
- "or each timeout seconds if repeat is True. If exit is True, "
- "call _exit(1) which is not safe.")},
- {"cancel_dump_traceback_later",
- faulthandler_cancel_dump_traceback_later_py, METH_NOARGS,
- PyDoc_STR("cancel_dump_traceback_later($module, /)\n--\n\n"
- "Cancel the previous call to dump_traceback_later().")},
+ FAULTHANDLER_PY_ENABLE_METHODDEF
+ FAULTHANDLER_DISABLE_PY_METHODDEF
+ FAULTHANDLER_IS_ENABLED_METHODDEF
+ FAULTHANDLER_DUMP_TRACEBACK_PY_METHODDEF
+ FAULTHANDLER_DUMP_C_STACK_PY_METHODDEF
+ FAULTHANDLER_DUMP_TRACEBACK_LATER_METHODDEF
+ FAULTHANDLER_CANCEL_DUMP_TRACEBACK_LATER_PY_METHODDEF
#ifdef FAULTHANDLER_USER
- {"register",
- _PyCFunction_CAST(faulthandler_register_py), METH_VARARGS|METH_KEYWORDS,
- PyDoc_STR("register($module, /, signum, file=sys.stderr, all_threads=True, chain=False)\n--\n\n"
- "Register a handler for the signal 'signum': dump the "
- "traceback of the current thread, or of all threads if "
- "all_threads is True, into file.")},
- {"unregister",
- _PyCFunction_CAST(faulthandler_unregister_py), METH_VARARGS,
- PyDoc_STR("unregister($module, signum, /)\n--\n\n"
- "Unregister the handler of the signal "
- "'signum' registered by register().")},
+ FAULTHANDLER_REGISTER_PY_METHODDEF
+ FAULTHANDLER_UNREGISTER_PY_METHODDEF
#endif
- {"_sigsegv", faulthandler_sigsegv, METH_VARARGS,
- PyDoc_STR("_sigsegv($module, release_gil=False, /)\n--\n\n"
- "Raise a SIGSEGV signal.")},
- {"_fatal_error_c_thread", faulthandler_fatal_error_c_thread, METH_NOARGS,
- PyDoc_STR("_fatal_error_c_thread($module, /)\n--\n\n"
- "Call Py_FatalError() in a new C thread.")},
- {"_sigabrt", faulthandler_sigabrt, METH_NOARGS,
- PyDoc_STR("_sigabrt($module, /)\n--\n\n"
- "Raise a SIGABRT signal.")},
- {"_sigfpe", faulthandler_sigfpe, METH_NOARGS,
- PyDoc_STR("_sigfpe($module, /)\n--\n\n"
- "Raise a SIGFPE signal.")},
+ FAULTHANDLER__SIGSEGV_METHODDEF
+ FAULTHANDLER__FATAL_ERROR_C_THREAD_METHODDEF
+ FAULTHANDLER__SIGABRT_METHODDEF
+ FAULTHANDLER__SIGFPE_METHODDEF
#ifdef FAULTHANDLER_STACK_OVERFLOW
- {"_stack_overflow", faulthandler_stack_overflow, METH_NOARGS,
- PyDoc_STR("_stack_overflow($module, /)\n--\n\n"
- "Recursive call to raise a stack overflow.")},
+ FAULTHANDLER__STACK_OVERFLOW_METHODDEF
#endif
#ifdef MS_WINDOWS
- {"_raise_exception", faulthandler_raise_exception, METH_VARARGS,
- PyDoc_STR("_raise_exception($module, code, flags=0, /)\n--\n\n"
- "Call RaiseException(code, flags).")},
+ FAULTHANDLER__RAISE_EXCEPTION_METHODDEF
#endif
{NULL, NULL} /* sentinel */
};
/* Add constants for unit tests */
#ifdef MS_WINDOWS
/* RaiseException() codes (prefixed by an underscore) */
- if (PyModule_AddIntConstant(module, "_EXCEPTION_ACCESS_VIOLATION",
- EXCEPTION_ACCESS_VIOLATION)) {
+ if (PyModule_Add(module, "_EXCEPTION_ACCESS_VIOLATION",
+ PyLong_FromUnsignedLong(EXCEPTION_ACCESS_VIOLATION))) {
return -1;
}
- if (PyModule_AddIntConstant(module, "_EXCEPTION_INT_DIVIDE_BY_ZERO",
- EXCEPTION_INT_DIVIDE_BY_ZERO)) {
+ if (PyModule_Add(module, "_EXCEPTION_INT_DIVIDE_BY_ZERO",
+ PyLong_FromUnsignedLong(EXCEPTION_INT_DIVIDE_BY_ZERO))) {
return -1;
}
- if (PyModule_AddIntConstant(module, "_EXCEPTION_STACK_OVERFLOW",
- EXCEPTION_STACK_OVERFLOW)) {
+ if (PyModule_Add(module, "_EXCEPTION_STACK_OVERFLOW",
+ PyLong_FromUnsignedLong(EXCEPTION_STACK_OVERFLOW))) {
return -1;
}
/* RaiseException() flags (prefixed by an underscore) */
- if (PyModule_AddIntConstant(module, "_EXCEPTION_NONCONTINUABLE",
- EXCEPTION_NONCONTINUABLE)) {
+ if (PyModule_Add(module, "_EXCEPTION_NONCONTINUABLE",
+ PyLong_FromUnsignedLong(EXCEPTION_NONCONTINUABLE))) {
return -1;
}
- if (PyModule_AddIntConstant(module, "_EXCEPTION_NONCONTINUABLE_EXCEPTION",
- EXCEPTION_NONCONTINUABLE_EXCEPTION)) {
+ if (PyModule_Add(module, "_EXCEPTION_NONCONTINUABLE_EXCEPTION",
+ PyLong_FromUnsignedLong(EXCEPTION_NONCONTINUABLE_EXCEPTION))) {
return -1;
}
#endif