Commit a01ca12a authored by Victor Stinner's avatar Victor Stinner

Issue #11393: Fix faulthandler.disable() and add a test

parent d727e232
...@@ -431,13 +431,15 @@ if file is not None: ...@@ -431,13 +431,15 @@ if file is not None:
@unittest.skipIf(not hasattr(faulthandler, "register"), @unittest.skipIf(not hasattr(faulthandler, "register"),
"need faulthandler.register") "need faulthandler.register")
def check_register(self, filename=False, all_threads=False): def check_register(self, filename=False, all_threads=False,
unregister=False):
""" """
Register a handler displaying the traceback on a user signal. Raise the Register a handler displaying the traceback on a user signal. Raise the
signal and check the written traceback. signal and check the written traceback.
Raise an error if the output doesn't match the expected format. Raise an error if the output doesn't match the expected format.
""" """
signum = signal.SIGUSR1
code = """ code = """
import faulthandler import faulthandler
import os import os
...@@ -446,12 +448,15 @@ import signal ...@@ -446,12 +448,15 @@ import signal
def func(signum): def func(signum):
os.kill(os.getpid(), signum) os.kill(os.getpid(), signum)
signum = signal.SIGUSR1 signum = {signum}
unregister = {unregister}
if {has_filename}: if {has_filename}:
file = open({filename}, "wb") file = open({filename}, "wb")
else: else:
file = None file = None
faulthandler.register(signum, file=file, all_threads={all_threads}) faulthandler.register(signum, file=file, all_threads={all_threads})
if unregister:
faulthandler.unregister(signum)
func(signum) func(signum)
if file is not None: if file is not None:
file.close() file.close()
...@@ -460,20 +465,31 @@ if file is not None: ...@@ -460,20 +465,31 @@ if file is not None:
filename=repr(filename), filename=repr(filename),
has_filename=bool(filename), has_filename=bool(filename),
all_threads=all_threads, all_threads=all_threads,
signum=signum,
unregister=unregister,
) )
trace, exitcode = self.get_output(code, filename) trace, exitcode = self.get_output(code, filename)
trace = '\n'.join(trace) trace = '\n'.join(trace)
if all_threads: if not unregister:
regex = 'Current thread XXX:\n' if all_threads:
regex = 'Current thread XXX:\n'
else:
regex = 'Traceback \(most recent call first\):\n'
regex = expected_traceback(6, 17, regex)
self.assertRegex(trace, regex)
else: else:
regex = 'Traceback \(most recent call first\):\n' self.assertEqual(trace, '')
regex = expected_traceback(6, 14, regex) if unregister:
self.assertRegex(trace, regex) self.assertNotEqual(exitcode, 0)
self.assertEqual(exitcode, 0) else:
self.assertEqual(exitcode, 0)
def test_register(self): def test_register(self):
self.check_register() self.check_register()
def test_unregister(self):
self.check_register(unregister=True)
def test_register_file(self): def test_register_file(self):
with temporary_filename() as filename: with temporary_filename() as filename:
self.check_register(filename=filename) self.check_register(filename=filename)
......
...@@ -628,7 +628,7 @@ faulthandler_register(PyObject *self, ...@@ -628,7 +628,7 @@ faulthandler_register(PyObject *self,
static int static int
faulthandler_unregister(user_signal_t *user, int signum) faulthandler_unregister(user_signal_t *user, int signum)
{ {
if (user->enabled) if (!user->enabled)
return 0; return 0;
user->enabled = 0; user->enabled = 0;
#ifdef HAVE_SIGACTION #ifdef HAVE_SIGACTION
...@@ -976,7 +976,7 @@ int _PyFaulthandler_Init(void) ...@@ -976,7 +976,7 @@ int _PyFaulthandler_Init(void)
void _PyFaulthandler_Fini(void) void _PyFaulthandler_Fini(void)
{ {
#ifdef FAULTHANDLER_USER #ifdef FAULTHANDLER_USER
unsigned int i; unsigned int signum;
#endif #endif
#ifdef FAULTHANDLER_LATER #ifdef FAULTHANDLER_LATER
...@@ -995,8 +995,8 @@ void _PyFaulthandler_Fini(void) ...@@ -995,8 +995,8 @@ void _PyFaulthandler_Fini(void)
#ifdef FAULTHANDLER_USER #ifdef FAULTHANDLER_USER
/* user */ /* user */
if (user_signals != NULL) { if (user_signals != NULL) {
for (i=0; i < NSIG; i++) for (signum=0; signum < NSIG; signum++)
faulthandler_unregister(&user_signals[i], i+1); faulthandler_unregister(&user_signals[signum], signum);
free(user_signals); free(user_signals);
user_signals = NULL; user_signals = NULL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment