diff --git a/Lib/test/test_faulthandler.py b/Lib/test/test_faulthandler.py --- a/Lib/test/test_faulthandler.py +++ b/Lib/test/test_faulthandler.py @@ -32,8 +32,8 @@ else: def expected_traceback(lineno1, lineno2, header, min_count=1): regex = header - regex += ' File "", line %s in func\n' % lineno1 - regex += ' File "", line %s in ' % lineno2 + regex += ' File "", line %s in \n' % lineno2 + regex += ' File "", line %s in func' % lineno1 if 1 < min_count: return '^' + (regex + '\n') * (min_count - 1) + regex else: @@ -286,9 +286,9 @@ funcA() lineno = 8 expected = [ 'Traceback (most recent call first):', + ' File "", line 13 in ', + ' File "", line 11 in funcA', ' File "", line %s in funcB' % lineno, - ' File "", line 11 in funcA', - ' File "", line 13 in ' ] trace, exitcode = self.get_output(code, filename) self.assertEqual(trace, expected) @@ -348,14 +348,14 @@ waiter.join() lineno = 10 regex = """ ^Thread 0x[0-9a-f]+: + File ".*threading.py", line [0-9]+ in _bootstrap + File ".*threading.py", line [0-9]+ in _bootstrap_inner + File "", line 23 in run (?: File ".*threading.py", line [0-9]+ in [_a-z]+ -){{1,3}} File "", line 23 in run - File ".*threading.py", line [0-9]+ in _bootstrap_inner - File ".*threading.py", line [0-9]+ in _bootstrap - +){{1,3}} Current thread XXX: - File "", line {lineno} in dump - File "", line 28 in $ + File "", line 28 in + File "", line {lineno} in dump$ """.strip() regex = regex.format(lineno=lineno) self.assertRegex(output, regex) diff --git a/Python/traceback.c b/Python/traceback.c --- a/Python/traceback.c +++ b/Python/traceback.c @@ -580,20 +580,36 @@ dump_frame(int fd, PyFrameObject *frame) write(fd, "\n", 1); } +static PyFrameObject * +reverse_frames(PyFrameObject *frame) +{ + /* Reverse the frame stack by exchanging pointers */ + PyFrameObject *prev = NULL, *next; + while (frame != NULL && PyFrame_Check(frame)) { + next = frame->f_back; + frame->f_back = prev; + prev = frame; + frame = next; + } + return prev; +} + static void dump_traceback(int fd, PyThreadState *tstate, int write_header) { - PyFrameObject *frame; + PyFrameObject *first, *frame; unsigned int depth; if (write_header) PUTS(fd, "Traceback (most recent call first):\n"); - frame = _PyThreadState_GetFrame(tstate); - if (frame == NULL) + first = _PyThreadState_GetFrame(tstate); + if (first == NULL) return; depth = 0; + first = reverse_frames(first); + frame = first; while (frame != NULL) { if (MAX_FRAME_DEPTH <= depth) { PUTS(fd, " ...\n"); @@ -605,6 +621,7 @@ dump_traceback(int fd, PyThreadState *ts frame = frame->f_back; depth++; } + (void) reverse_frames(first); } void