Skip to content

Commit 9ab9696

Browse files
committed
faulthandler: don't dump all threads when running without the GIL
It's not safe to access other threads stacks when running without the GIL.
1 parent 964bb33 commit 9ab9696

File tree

5 files changed

+25
-7
lines changed

5 files changed

+25
-7
lines changed

Lib/test/support/script_helper.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def interpreter_requires_environment():
3939
global __cached_interp_requires_environment
4040
if __cached_interp_requires_environment is None:
4141
# If PYTHONHOME is set, assume that we need it
42-
if 'PYTHONHOME' in os.environ:
42+
if 'PYTHONHOME' in os.environ or 'PYTHONGIL' in os.environ:
4343
__cached_interp_requires_environment = True
4444
return True
4545
# cannot run subprocess, assume we don't need it

Lib/test/test_capi/test_misc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ def test_getitem_with_error(self):
311311
r'Python runtime state: initialized\n'
312312
r'ValueError: bug\n'
313313
r'\n'
314-
r'Current thread .* \(most recent call first\):\n'
314+
r'(Current thread|Stack).* \(most recent call first\):\n'
315315
r' File .*, line 6 in <module>\n'
316316
r'\n'
317317
r'Extension modules: _testcapi \(total: 1\)\n')

Lib/test/test_faulthandler.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,21 +95,25 @@ def check_error(self, code, lineno, fatal_error, *,
9595
9696
Raise an error if the output doesn't match the expected format.
9797
"""
98+
if sys.flags.nogil:
99+
all_threads = False
98100
if all_threads:
99101
if know_current_thread:
100102
header = 'Current thread 0x[0-9a-f]+'
101103
else:
102104
header = 'Thread 0x[0-9a-f]+'
103-
else:
105+
elif know_current_thread:
104106
header = 'Stack'
105107
regex = [f'^{fatal_error}']
106108
if py_fatal_error:
107109
regex.append("Python runtime state: initialized")
108110
regex.append('')
109-
regex.append(fr'{header} \(most recent call first\):')
110-
if garbage_collecting:
111+
if all_threads or know_current_thread:
112+
regex.append(fr'{header} \(most recent call first\):')
113+
if garbage_collecting and all_threads:
111114
regex.append(' Garbage-collecting')
112-
regex.append(fr' File "<string>", line {lineno} in {function}')
115+
if all_threads or know_current_thread:
116+
regex.append(fr' File "<string>", line {lineno} in {function}')
113117
regex = '\n'.join(regex)
114118

115119
if other_regex:
@@ -691,6 +695,8 @@ def check_register(self, filename=False, all_threads=False,
691695
692696
Raise an error if the output doesn't match the expected format.
693697
"""
698+
if sys.flags.nogil:
699+
all_threads = False
694700
signum = signal.SIGUSR1
695701
code = """
696702
import faulthandler

Modules/faulthandler.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,11 @@ faulthandler_dump_traceback(int fd, int all_threads,
183183

184184
reentrant = 1;
185185

186+
if (_PyRuntime.preconfig.disable_gil) {
187+
// It's not safe to dump all threads when running without the GIL.
188+
all_threads = 0;
189+
}
190+
186191
/* SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL are synchronous signals and
187192
are thus delivered to the thread that caused the fault. Get the Python
188193
thread state of the current thread.

Python/pylifecycle.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2559,7 +2559,14 @@ _Py_FatalError_DumpTracebacks(int fd, PyInterpreterState *interp,
25592559
PUTS(fd, "\n");
25602560

25612561
/* display the current Python stack */
2562-
_Py_DumpTracebackThreads(fd, interp, tstate);
2562+
if (_PyRuntime.preconfig.disable_gil) {
2563+
if (tstate != NULL) {
2564+
_Py_DumpTraceback(fd, tstate);
2565+
}
2566+
}
2567+
else {
2568+
_Py_DumpTracebackThreads(fd, interp, tstate);
2569+
}
25632570
}
25642571

25652572
/* Print the current exception (if an exception is set) with its traceback,

0 commit comments

Comments
 (0)