Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0a963fb

Browse files
authored
bpo-38203: faulthandler.dump_traceback_later() is always available (GH-16249)
dump_traceback_later() and cancel_dump_traceback_later() functions of the faulthandler module are always available since Python 3.7.
1 parent da57599 commit 0a963fb

6 files changed

Lines changed: 10 additions & 38 deletions

File tree

Doc/library/faulthandler.rst

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,10 @@ Dumping the tracebacks after a timeout
100100
:func:`cancel_dump_traceback_later` is called: see :ref:`issue with file
101101
descriptors <faulthandler-fd>`.
102102

103-
This function is implemented using a watchdog thread and therefore is not
104-
available if Python is compiled with threads disabled.
103+
This function is implemented using a watchdog thread.
104+
105+
.. versionchanged:: 3.7
106+
This function is now always available.
105107

106108
.. versionchanged:: 3.5
107109
Added support for passing file descriptor to this function.

Lib/test/eintrdata/eintr_tester.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,8 @@ def setUp(self):
5757

5858
# Use faulthandler as watchdog to debug when a test hangs
5959
# (timeout of 10 minutes)
60-
if hasattr(faulthandler, 'dump_traceback_later'):
61-
faulthandler.dump_traceback_later(10 * 60, exit=True,
62-
file=sys.__stderr__)
60+
faulthandler.dump_traceback_later(10 * 60, exit=True,
61+
file=sys.__stderr__)
6362

6463
@staticmethod
6564
def stop_alarm():
@@ -68,8 +67,7 @@ def stop_alarm():
6867
def tearDown(self):
6968
self.stop_alarm()
7069
signal.signal(signal.SIGALRM, self.orig_handler)
71-
if hasattr(faulthandler, 'cancel_dump_traceback_later'):
72-
faulthandler.cancel_dump_traceback_later()
70+
faulthandler.cancel_dump_traceback_later()
7371

7472
def subprocess(self, *args, **kw):
7573
cmd_args = (sys.executable, '-c') + args

Lib/test/libregrtest/main.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -164,11 +164,6 @@ def display_progress(self, test_index, text):
164164
def parse_args(self, kwargs):
165165
ns = _parse_args(sys.argv[1:], **kwargs)
166166

167-
if ns.timeout and not hasattr(faulthandler, 'dump_traceback_later'):
168-
print("Warning: The timeout option requires "
169-
"faulthandler.dump_traceback_later", file=sys.stderr)
170-
ns.timeout = None
171-
172167
if ns.xmlpath:
173168
support.junit_xml_list = self.testsuite_xml = []
174169

Lib/test/test_faulthandler.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -535,8 +535,6 @@ def test_dump_traceback_threads_file(self):
535535
with temporary_filename() as filename:
536536
self.check_dump_traceback_threads(filename)
537537

538-
@unittest.skipIf(not hasattr(faulthandler, 'dump_traceback_later'),
539-
'need faulthandler.dump_traceback_later()')
540538
def check_dump_traceback_later(self, repeat=False, cancel=False, loops=1,
541539
*, filename=None, fd=None):
542540
"""
@@ -744,9 +742,8 @@ def test_stderr_None(self):
744742
faulthandler.enable()
745743
with self.check_stderr_none():
746744
faulthandler.dump_traceback()
747-
if hasattr(faulthandler, 'dump_traceback_later'):
748-
with self.check_stderr_none():
749-
faulthandler.dump_traceback_later(1e-3)
745+
with self.check_stderr_none():
746+
faulthandler.dump_traceback_later(1e-3)
750747
if hasattr(faulthandler, "register"):
751748
with self.check_stderr_none():
752749
faulthandler.register(signal.SIGUSR1)

Lib/test/test_regrtest.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,6 @@ def test_help(self):
5454
libregrtest._parse_args([opt])
5555
self.assertIn('Run Python regression tests.', out.getvalue())
5656

57-
@unittest.skipUnless(hasattr(faulthandler, 'dump_traceback_later'),
58-
"faulthandler.dump_traceback_later() required")
5957
def test_timeout(self):
6058
ns = libregrtest._parse_args(['--timeout', '4.2'])
6159
self.assertEqual(ns.timeout, 4.2)
@@ -572,8 +570,7 @@ def setUp(self):
572570
self.python_args = ['-Wd', '-E', '-bb']
573571
self.regrtest_args = ['-uall', '-rwW',
574572
'--testdir=%s' % self.tmptestdir]
575-
if hasattr(faulthandler, 'dump_traceback_later'):
576-
self.regrtest_args.extend(('--timeout', '3600', '-j4'))
573+
self.regrtest_args.extend(('--timeout', '3600', '-j4'))
577574
if sys.platform == 'win32':
578575
self.regrtest_args.append('-n')
579576

Modules/faulthandler.c

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@
1919
/* Allocate at maximum 100 MiB of the stack to raise the stack overflow */
2020
#define STACK_OVERFLOW_MAX_SIZE (100 * 1024 * 1024)
2121

22-
#define FAULTHANDLER_LATER
23-
2422
#ifndef MS_WINDOWS
2523
/* register() is useless on Windows, because only SIGSEGV, SIGABRT and
2624
SIGILL can be handled by the process, and these signals can only be used
@@ -60,7 +58,6 @@ static struct {
6058
#endif
6159
} fatal_error = {0, NULL, -1, 0};
6260

63-
#ifdef FAULTHANDLER_LATER
6461
static struct {
6562
PyObject *file;
6663
int fd;
@@ -77,7 +74,6 @@ static struct {
7774
/* released by child thread when joined */
7875
PyThread_type_lock running;
7976
} thread;
80-
#endif
8177

8278
#ifdef FAULTHANDLER_USER
8379
typedef struct {
@@ -589,8 +585,6 @@ faulthandler_is_enabled(PyObject *self, PyObject *Py_UNUSED(ignored))
589585
return PyBool_FromLong(fatal_error.enabled);
590586
}
591587

592-
#ifdef FAULTHANDLER_LATER
593-
594588
static void
595589
faulthandler_thread(void *unused)
596590
{
@@ -790,7 +784,6 @@ faulthandler_cancel_dump_traceback_later_py(PyObject *self,
790784
cancel_dump_traceback_later();
791785
Py_RETURN_NONE;
792786
}
793-
#endif /* FAULTHANDLER_LATER */
794787

795788

796789
#ifdef FAULTHANDLER_USER
@@ -1230,9 +1223,7 @@ faulthandler_stack_overflow(PyObject *self, PyObject *Py_UNUSED(ignored))
12301223
static int
12311224
faulthandler_traverse(PyObject *module, visitproc visit, void *arg)
12321225
{
1233-
#ifdef FAULTHANDLER_LATER
12341226
Py_VISIT(thread.file);
1235-
#endif
12361227
#ifdef FAULTHANDLER_USER
12371228
if (user_signals != NULL) {
12381229
for (size_t signum=0; signum < NSIG; signum++)
@@ -1273,7 +1264,6 @@ static PyMethodDef module_methods[] = {
12731264
PyDoc_STR("dump_traceback(file=sys.stderr, all_threads=True): "
12741265
"dump the traceback of the current thread, or of all threads "
12751266
"if all_threads is True, into file")},
1276-
#ifdef FAULTHANDLER_LATER
12771267
{"dump_traceback_later",
12781268
(PyCFunction)(void(*)(void))faulthandler_dump_traceback_later, METH_VARARGS|METH_KEYWORDS,
12791269
PyDoc_STR("dump_traceback_later(timeout, repeat=False, file=sys.stderrn, exit=False):\n"
@@ -1284,8 +1274,6 @@ static PyMethodDef module_methods[] = {
12841274
faulthandler_cancel_dump_traceback_later_py, METH_NOARGS,
12851275
PyDoc_STR("cancel_dump_traceback_later():\ncancel the previous call "
12861276
"to dump_traceback_later().")},
1287-
#endif
1288-
12891277
#ifdef FAULTHANDLER_USER
12901278
{"register",
12911279
(PyCFunction)(void(*)(void))faulthandler_register_py, METH_VARARGS|METH_KEYWORDS,
@@ -1298,7 +1286,6 @@ static PyMethodDef module_methods[] = {
12981286
PyDoc_STR("unregister(signum): unregister the handler of the signal "
12991287
"'signum' registered by register()")},
13001288
#endif
1301-
13021289
{"_read_null", faulthandler_read_null, METH_NOARGS,
13031290
PyDoc_STR("_read_null(): read from NULL, raise "
13041291
"a SIGSEGV or SIGBUS signal depending on the platform")},
@@ -1399,9 +1386,7 @@ _PyFaulthandler_Init(int enable)
13991386
stack.ss_size = SIGSTKSZ * 2;
14001387
#endif
14011388

1402-
#ifdef FAULTHANDLER_LATER
14031389
memset(&thread, 0, sizeof(thread));
1404-
#endif
14051390

14061391
if (enable) {
14071392
if (faulthandler_init_enable() < 0) {
@@ -1413,7 +1398,6 @@ _PyFaulthandler_Init(int enable)
14131398

14141399
void _PyFaulthandler_Fini(void)
14151400
{
1416-
#ifdef FAULTHANDLER_LATER
14171401
/* later */
14181402
if (thread.cancel_event) {
14191403
cancel_dump_traceback_later();
@@ -1425,7 +1409,6 @@ void _PyFaulthandler_Fini(void)
14251409
PyThread_free_lock(thread.running);
14261410
thread.running = NULL;
14271411
}
1428-
#endif
14291412

14301413
#ifdef FAULTHANDLER_USER
14311414
/* user */

0 commit comments

Comments
 (0)