File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -221,6 +221,27 @@ def test_return(self):
221221 def test_exception (self ):
222222 self .run_test_for_event ('exception' )
223223
224+ def test_trash_stack (self ):
225+ def f ():
226+ for i in range (5 ):
227+ print i # line tracing will raise an exception at this line
228+
229+ def g (frame , why , extra ):
230+ if (why == 'line' and
231+ frame .f_lineno == f .func_code .co_firstlineno + 2 ):
232+ raise RuntimeError , "i am crashing"
233+ return g
234+
235+ sys .settrace (g )
236+ try :
237+ f ()
238+ except RuntimeError :
239+ # the test is really that this doesn't segfault:
240+ import gc
241+ gc .collect ()
242+ else :
243+ self .fail ("exception not propagated" )
244+
224245
225246# 'Jump' tests: assigning to frame.f_lineno within a trace function
226247# moves the execution position - it's how debuggers implement a Jump
Original file line number Diff line number Diff line change @@ -819,18 +819,19 @@ eval_frame(PyFrameObject *f)
819819 for expository comments */
820820 f -> f_stacktop = stack_pointer ;
821821
822- if (maybe_call_line_trace (tstate -> c_tracefunc ,
823- tstate -> c_traceobj ,
824- f , & instr_lb , & instr_ub )) {
822+ err = maybe_call_line_trace (tstate -> c_tracefunc ,
823+ tstate -> c_traceobj ,
824+ f , & instr_lb , & instr_ub );
825+ /* Reload possibly changed frame fields */
826+ JUMPTO (f -> f_lasti );
827+ if (f -> f_stacktop != NULL ) {
828+ stack_pointer = f -> f_stacktop ;
829+ f -> f_stacktop = NULL ;
830+ }
831+ if (err ) {
825832 /* trace function raised an exception */
826- why = WHY_EXCEPTION ;
827833 goto on_error ;
828834 }
829- /* Reload possibly changed frame fields */
830- JUMPTO (f -> f_lasti );
831- stack_pointer = f -> f_stacktop ;
832- assert (stack_pointer != NULL );
833- f -> f_stacktop = NULL ;
834835 }
835836
836837 /* Extract opcode and argument */
You can’t perform that action at this time.
0 commit comments