mirror of
https://github.com/python/cpython.git
synced 2025-09-26 10:19:53 +00:00
[3.11] gh-94215: Fix error handling for line-tracing events (GH-94681) (GH-94688)
* Re-enable crasher
* Fix error handling for line-tracing events
* blurb add
(cherry picked from commit 23ee4a8067
)
Co-authored-by: Brandt Bucher <brandtbucher@microsoft.com>
This commit is contained in:
parent
73a1800b55
commit
36a3372d51
3 changed files with 17 additions and 6 deletions
|
@ -2085,7 +2085,6 @@ def bœr():
|
||||||
expected = '(Pdb) The correct file was executed'
|
expected = '(Pdb) The correct file was executed'
|
||||||
self.assertEqual(stdout.split('\n')[6].rstrip('\r'), expected)
|
self.assertEqual(stdout.split('\n')[6].rstrip('\r'), expected)
|
||||||
|
|
||||||
@unittest.skip("test crashes, see gh-94215")
|
|
||||||
def test_gh_94215_crash(self):
|
def test_gh_94215_crash(self):
|
||||||
script = """\
|
script = """\
|
||||||
def func():
|
def func():
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
Fix an issue where exceptions raised by line-tracing events would cause
|
||||||
|
frames to be left in an invalid state, possibly resulting in a hard crash of
|
||||||
|
the interpreter.
|
|
@ -5642,16 +5642,25 @@ handle_eval_breaker:
|
||||||
err = maybe_call_line_trace(tstate->c_tracefunc,
|
err = maybe_call_line_trace(tstate->c_tracefunc,
|
||||||
tstate->c_traceobj,
|
tstate->c_traceobj,
|
||||||
tstate, frame, instr_prev);
|
tstate, frame, instr_prev);
|
||||||
|
// Reload possibly changed frame fields:
|
||||||
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
|
frame->stacktop = -1;
|
||||||
|
// next_instr is only reloaded if tracing *does not* raise.
|
||||||
|
// This is consistent with the behavior of older Python
|
||||||
|
// versions. If a trace function sets a new f_lineno and
|
||||||
|
// *then* raises, we use the *old* location when searching
|
||||||
|
// for an exception handler, displaying the traceback, and
|
||||||
|
// so on:
|
||||||
if (err) {
|
if (err) {
|
||||||
/* trace function raised an exception */
|
// next_instr wasn't incremented at the start of this
|
||||||
|
// instruction. Increment it before handling the error,
|
||||||
|
// so that it looks the same as a "normal" instruction:
|
||||||
next_instr++;
|
next_instr++;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
/* Reload possibly changed frame fields */
|
// Reload next_instr. Don't increment it, though, since
|
||||||
|
// we're going to re-dispatch to the "true" instruction now:
|
||||||
next_instr = frame->prev_instr;
|
next_instr = frame->prev_instr;
|
||||||
|
|
||||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
|
||||||
frame->stacktop = -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue