]> granicus.if.org Git - python/commitdiff
Armin Rigo's fix & test for
authorMichael W. Hudson <mwh@python.net>
Tue, 29 Apr 2003 16:18:47 +0000 (16:18 +0000)
committerMichael W. Hudson <mwh@python.net>
Tue, 29 Apr 2003 16:18:47 +0000 (16:18 +0000)
[ 729622 ] line tracing hook errors

with massaging from me to integrate test into test suite.

Lib/test/test_trace.py
Python/ceval.c

index f973a1939350983c64dd4b8701a8895517801d2c..21e5ca9aba9b1b37e74198b5490dac0dd7520579 100644 (file)
@@ -221,6 +221,27 @@ class RaisingTraceFuncTestCase(unittest.TestCase):
     def test_exception(self):
         self.run_test_for_event('exception')
 
+    def test_trash_stack(self):
+        def f():
+            for i in range(5):
+                print i  # line tracing will raise an exception at this line
+
+        def g(frame, why, extra):
+            if (why == 'line' and
+                frame.f_lineno == f.func_code.co_firstlineno + 2):
+                raise RuntimeError, "i am crashing"
+            return g
+
+        sys.settrace(g)
+        try:
+            f()
+        except RuntimeError:
+            # the test is really that this doesn't segfault:
+            import gc
+            gc.collect()
+        else:
+            self.fail("exception not propagated")
+
 
 # 'Jump' tests: assigning to frame.f_lineno within a trace function
 # moves the execution position - it's how debuggers implement a Jump
index 3ea1bdc966cbf2dd7b01b67fd6c7015065f07451..abefd32f12a9bf83a8066ccfd44771a49f224022 100644 (file)
@@ -819,18 +819,19 @@ eval_frame(PyFrameObject *f)
                           for expository comments */
                        f->f_stacktop = stack_pointer;
                        
-                       if (maybe_call_line_trace(tstate->c_tracefunc,
-                                                 tstate->c_traceobj,
-                                                 f, &instr_lb, &instr_ub)) {
+                       err = maybe_call_line_trace(tstate->c_tracefunc,
+                                                   tstate->c_traceobj,
+                                                   f, &instr_lb, &instr_ub);
+                       /* Reload possibly changed frame fields */
+                       JUMPTO(f->f_lasti);
+                       if (f->f_stacktop != NULL) {
+                               stack_pointer = f->f_stacktop;
+                               f->f_stacktop = NULL;
+                       }
+                       if (err) {
                                /* trace function raised an exception */
-                               why = WHY_EXCEPTION;
                                goto on_error;
                        }
-                       /* Reload possibly changed frame fields */
-                       JUMPTO(f->f_lasti);
-                       stack_pointer = f->f_stacktop;
-                       assert(stack_pointer != NULL);
-                       f->f_stacktop = NULL;
                }
 
                /* Extract opcode and argument */