changeset 25319:56201aad3462 stable

avoid crash on exceptions thrown in handle class delete method * ov-classdef (handle_cdef_object::~handle_cdef_object): Use same technique as in octave_oncleanup::~octave_oncleanup to avoid crashes if exceptions are thrown while executing handle class delete method while inside C++ class destructor.
author John W. Eaton <jwe@octave.org>
date Thu, 26 Apr 2018 21:39:22 -0400
parents b328ff3ce0f7
children 2ad00275b79b 2540fde5f07b 4c14c002cabe
files libinterp/octave-value/ov-classdef.cc
diffstat 1 files changed, 40 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/octave-value/ov-classdef.cc	Thu Nov 02 10:27:11 2017 -0700
+++ b/libinterp/octave-value/ov-classdef.cc	Thu Apr 26 21:39:22 2018 -0400
@@ -1788,8 +1788,46 @@
 
 handle_cdef_object::~handle_cdef_object (void)
 {
-  // Call classdef "delete()" method on object
-  get_class ().delete_object (get_class ());
+  octave::unwind_protect frame;
+
+  // Clear interrupts.
+  frame.protect_var (octave_interrupt_state);
+  octave_interrupt_state = 0;
+
+  // Disallow quit().
+  frame.protect_var (quit_allowed);
+  quit_allowed = false;
+
+  interpreter_try (frame);
+
+  try
+    {
+      // Call classdef "delete()" method on object
+      get_class ().delete_object (get_class ());
+    }
+  catch (const octave::interrupt_exception&)
+    {
+      octave::interpreter::recover_from_exception ();
+
+      warning ("interrupt occurred in handle class delete method");
+    }
+  catch (const octave::execution_exception&)
+    {
+      std::string msg = last_error_message ();
+      warning ("error caught while executing handle class delete method:\n%s\n",
+               msg.c_str ());
+
+    }
+  catch (const octave::exit_exception&)
+    {
+      // This shouldn't happen since we disabled quit above.
+      warning ("exit disabled while executing handle class delete method");
+    }
+  catch (...) // Yes, the black hole.  We're in a d-tor.
+    {
+      // This shouldn't happen, in theory.
+      warning ("internal error: unhandled exception in handle class delete method");
+    }
 
 #if DEBUG_TRACE
   std::cerr << "deleting " << get_class ().get_name ()