27
27
MS_WINDOWS = (os .name == 'nt' )
28
28
29
29
30
- def expected_traceback (lineno1 , lineno2 , header , min_count = 1 ):
30
+ def expected_traceback (lineno1 , lineno2 , header , min_count = 1 , * , c_call_stack = True ):
31
31
regex = header
32
32
regex += ' File "<string>", line %s in func\n ' % lineno1
33
33
regex += ' File "<string>", line %s in <module>' % lineno2
34
34
if 1 < min_count :
35
+ assert not c_call_stack
35
36
return '^' + (regex + '\n ' ) * (min_count - 1 ) + regex
36
37
else :
37
- return '^' + regex + '$'
38
+ if c_call_stack :
39
+ return '^' + regex + "\n \n Current thread's C call stack"
40
+ else :
41
+ return '^' + regex + '$'
38
42
39
43
def skip_segfault_on_android (test ):
40
44
# Issue #32138: Raising SIGSEGV on Android may not cause a crash.
@@ -89,6 +93,7 @@ def check_error(self, code, lineno, fatal_error, *,
89
93
fd = None , know_current_thread = True ,
90
94
py_fatal_error = False ,
91
95
garbage_collecting = False ,
96
+ c_call_stack = True ,
92
97
function = '<module>' ):
93
98
"""
94
99
Check that the fault handler for fatal errors is enabled and check the
@@ -110,7 +115,19 @@ def check_error(self, code, lineno, fatal_error, *,
110
115
regex .append (fr'{ header } \(most recent call first\):' )
111
116
if garbage_collecting :
112
117
regex .append (' Garbage-collecting' )
113
- regex .append (fr' File "<string>", line { lineno } in { function } ' )
118
+ regex .append (
119
+ fr' File "<string>", line { lineno } in { function } '
120
+ r'(?:\n File "<string>", line \d+ in .*)*'
121
+ )
122
+ if c_call_stack :
123
+ regex .append ('' )
124
+ regex .append (r"Current thread's C call stack \(most recent call first\):" )
125
+ regex .append (
126
+ # First line should always be in the cfaulthandler shared library
127
+ fr"{ re .escape (cfaulthandler .__file__ )} \(.*\+0x[0-9a-f]+\)\[0x[0-9a-f]+\]"
128
+ # Remaining lines could be anywhere
129
+ r"(?:\n.*(?:\(.*\+0x[0-9a-f]+\))?\[0x[0-9a-f]+\])+"
130
+ )
114
131
regex = '\n ' .join (regex )
115
132
116
133
if other_regex :
@@ -212,7 +229,8 @@ def test_fatal_error_c_thread(self):
212
229
'in new thread' ,
213
230
know_current_thread = False ,
214
231
func = 'cfaulthandler_fatal_error_thread' ,
215
- py_fatal_error = True )
232
+ py_fatal_error = True ,
233
+ c_call_stack = False )
216
234
217
235
def test_sigabrt (self ):
218
236
self .check_fatal_error ("""
@@ -272,7 +290,8 @@ def check_fatal_error_func(self, release_gil):
272
290
2 ,
273
291
'xyz' ,
274
292
func = 'test_fatal_error' ,
275
- py_fatal_error = True )
293
+ py_fatal_error = True ,
294
+ c_call_stack = False )
276
295
277
296
def test_fatal_error (self ):
278
297
self .check_fatal_error_func (False )
@@ -451,14 +470,17 @@ def funcA():
451
470
lineno = 11
452
471
else :
453
472
lineno = 14
454
- expected = [
473
+ expected_start = [
455
474
'Stack (most recent call first):' ,
456
475
' File "<string>", line %s in funcB' % lineno ,
457
476
' File "<string>", line 17 in funcA' ,
458
- ' File "<string>", line 19 in <module>'
477
+ ' File "<string>", line 19 in <module>' ,
478
+ '' ,
479
+ "Current thread's C call stack (most recent call first):" ,
459
480
]
460
481
trace , exitcode = self .get_output (code , filename , fd )
461
- self .assertEqual (trace , expected )
482
+ self .assertEqual (trace [:len (expected_start )], expected_start )
483
+ self .assertRegex (trace [len (expected_start )], fr"{ re .escape (cfaulthandler .__file__ )} \(.*\+0x[0-9a-f]+\)\[0x[0-9a-f]+\]" )
462
484
self .assertEqual (exitcode , 0 )
463
485
464
486
def test_dump_traceback (self ):
@@ -495,7 +517,7 @@ def {func_name}():
495
517
' File "<string>", line 6 in <module>'
496
518
]
497
519
trace , exitcode = self .get_output (code )
498
- self .assertEqual (trace , expected )
520
+ self .assertEqual (trace [: len ( expected )] , expected )
499
521
self .assertEqual (exitcode , 0 )
500
522
501
523
def check_dump_traceback_threads (self , filename ):
@@ -551,7 +573,9 @@ def run(self):
551
573
552
574
Current thread 0x[0-9a-f]+ \(most recent call first\):
553
575
File "<string>", line {lineno} in dump
554
- File "<string>", line 28 in <module>$
576
+ File "<string>", line 28 in <module>
577
+
578
+ Current thread's C call stack \(most recent call first\):
555
579
"""
556
580
regex = dedent (regex .format (lineno = lineno )).strip ()
557
581
self .assertRegex (output , regex )
@@ -620,7 +644,7 @@ def func(timeout, repeat, cancel, file, loops):
620
644
if repeat :
621
645
count *= 2
622
646
header = r'Timeout \(%s\)!\nThread 0x[0-9a-f]+ \(most recent call first\):\n' % timeout_str
623
- regex = expected_traceback (17 , 26 , header , min_count = count )
647
+ regex = expected_traceback (17 , 26 , header , min_count = count , c_call_stack = False )
624
648
self .assertRegex (trace , regex )
625
649
else :
626
650
self .assertEqual (trace , '' )
0 commit comments