changeset 28980:a745a046b705 stable

handle debug_on_interrupt when execution_exception is caught (bug #59306) When debug_on_interrupt is true, avoid entering the debugger for execution_exceptions that are handled internally. Now we enter the debugger in a try/catcch block around each statement that is executed instead of at the point the exception is thrown. The other option to avoid the problem reported in bug #59306 would be to attempt to ensure that any internal try/catch block that handles execution_exception objects must disable debug_on_interrupt. * pt-eval.cc (tree_evaluator::visit_statement): Handle debug_on_interrupt action here. * error.cc (error_system::throw_error): Don't handle debug_on_interrupt action here.
author John W. Eaton <jwe@octave.org>
date Thu, 22 Oct 2020 11:15:54 -0400
parents 1152256be2cf
children d632d99d5c2e 6d37fa1a786e
files libinterp/corefcn/error.cc libinterp/parse-tree/pt-eval.cc
diffstat 2 files changed, 26 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/error.cc	Fri Feb 21 18:28:07 2020 +0100
+++ b/libinterp/corefcn/error.cc	Thu Oct 22 11:15:54 2020 -0400
@@ -893,25 +893,6 @@
 
   void error_system::throw_error (execution_exception& ex)
   {
-    tree_evaluator& tw = m_interpreter.get_evaluator ();
-
-    bp_table& bptab = tw.get_bp_table ();
-
-    if ((m_interpreter.interactive () || application::forced_interactive ())
-        && ((debug_on_error ()
-             && bptab.debug_on_err (last_error_id ()))
-            || (debug_on_caught ()
-                && bptab.debug_on_caught (last_error_id ())))
-        && tw.in_user_code ())
-      {
-        save_exception (ex);
-        display_exception (ex, std::cerr);
-
-        tw.enter_debugger ();
-      }
-
-    // Throw the exception even if we entered the debugger.
-
     throw ex;
   }
 
--- a/libinterp/parse-tree/pt-eval.cc	Fri Feb 21 18:28:07 2020 +0100
+++ b/libinterp/parse-tree/pt-eval.cc	Thu Oct 22 11:15:54 2020 -0400
@@ -3065,6 +3065,32 @@
             else
               throw;
           }
+        catch (const execution_exception& ee)
+          {
+            error_system& es = m_interpreter.get_error_system ();
+
+            if ((m_interpreter.interactive ()
+                 || application::forced_interactive ())
+                && ((es.debug_on_error ()
+                     && m_bp_table.debug_on_err (es.last_error_id ()))
+                    || (es.debug_on_caught ()
+                        && m_bp_table.debug_on_caught (es.last_error_id ())))
+                && in_user_code ())
+              {
+                es.save_exception (ee);
+                es.display_exception (ee, std::cerr);
+
+                enter_debugger ();
+
+                // It doesn't make sense to continue execution after an
+                // error occurs so force the debugger to quit all debug
+                // levels and return the the top prompt.
+
+                throw quit_debug_exception (true);
+              }
+            else
+              throw;
+          }
       }
   }