Skip to content

Commit e8d914f

Browse files
[3.15] gh-151278: Fix test_faulthandler on UBSan (GH-151279) (#151281)
gh-151278: Fix test_faulthandler on UBSan (GH-151279) * Py_FatalError() no longer calls _PyFaulthandler_Fini() if it doesn't hold the GIL. * Skip test_faulthandler tests raising signals if run with UBSan. * Enable test_faulthandler in GitHub Action "Reusable Sanitizer". (cherry picked from commit e60c42d) Co-authored-by: Victor Stinner <vstinner@python.org>
1 parent 10f616c commit e8d914f

3 files changed

Lines changed: 14 additions & 7 deletions

File tree

.github/workflows/reusable-san.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,13 @@ jobs:
8282
run: make -j4
8383
- name: Display build info
8484
run: make pythoninfo
85-
# test_{capi,faulthandler} are skipped under UBSan because
85+
# test_capi is skipped under UBSan because
8686
# they raise signals that UBSan with halt_on_error=1 intercepts.
8787
- name: Tests
8888
run: >-
8989
./python -m test
9090
${{ inputs.sanitizer == 'TSan' && '--tsan' || '' }}
91-
${{ inputs.sanitizer == 'UBSan' && '-x test_capi -x test_faulthandler' || '' }}
91+
${{ inputs.sanitizer == 'UBSan' && '-x test_capi' || '' }}
9292
-j4 -W
9393
- name: Parallel tests
9494
if: >-

Lib/test/test_faulthandler.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@
3333
CURRENT_THREAD_HEADER = fr'{CURRENT_THREAD_ID} \(most recent call first\):'
3434

3535

36+
def skip_if_sanitizer_signal(signame):
37+
return support.skip_if_sanitizer(f"TSAN/UBSan itercepts {signame}",
38+
thread=True, ub=True)
39+
40+
3641
def expected_traceback(lineno1, lineno2, header, min_count=1):
3742
regex = header
3843
regex += ' File "<string>", line %s in func\n' % lineno1
@@ -224,7 +229,7 @@ def test_fatal_error_c_thread(self):
224229
func='faulthandler_fatal_error_thread',
225230
py_fatal_error=True)
226231

227-
@support.skip_if_sanitizer("TSAN itercepts SIGABRT", thread=True)
232+
@skip_if_sanitizer_signal("SIGABRT")
228233
def test_sigabrt(self):
229234
self.check_fatal_error("""
230235
import faulthandler
@@ -236,7 +241,7 @@ def test_sigabrt(self):
236241

237242
@unittest.skipIf(sys.platform == 'win32',
238243
"SIGFPE cannot be caught on Windows")
239-
@support.skip_if_sanitizer("TSAN itercepts SIGFPE", thread=True)
244+
@skip_if_sanitizer_signal("SIGFPE")
240245
def test_sigfpe(self):
241246
self.check_fatal_error("""
242247
import faulthandler
@@ -248,7 +253,7 @@ def test_sigfpe(self):
248253

249254
@unittest.skipIf(_testcapi is None, 'need _testcapi')
250255
@unittest.skipUnless(hasattr(signal, 'SIGBUS'), 'need signal.SIGBUS')
251-
@support.skip_if_sanitizer("TSAN itercepts SIGBUS", thread=True)
256+
@skip_if_sanitizer_signal("SIGBUS")
252257
@skip_segfault_on_android
253258
def test_sigbus(self):
254259
self.check_fatal_error("""
@@ -263,7 +268,7 @@ def test_sigbus(self):
263268

264269
@unittest.skipIf(_testcapi is None, 'need _testcapi')
265270
@unittest.skipUnless(hasattr(signal, 'SIGILL'), 'need signal.SIGILL')
266-
@support.skip_if_sanitizer("TSAN itercepts SIGILL", thread=True)
271+
@skip_if_sanitizer_signal("SIGILL")
267272
@skip_segfault_on_android
268273
def test_sigill(self):
269274
self.check_fatal_error("""

Python/pylifecycle.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3724,7 +3724,9 @@ fatal_error(int fd, int header, const char *prefix, const char *msg,
37243724
This function already did its best to display a traceback.
37253725
Disable faulthandler to prevent writing a second traceback
37263726
on abort(). */
3727-
_PyFaulthandler_Fini();
3727+
if (has_tstate_and_gil) {
3728+
_PyFaulthandler_Fini();
3729+
}
37283730

37293731
/* Check if the current Python thread hold the GIL */
37303732
if (has_tstate_and_gil) {

0 commit comments

Comments
 (0)