# HG changeset patch # User John W. Eaton # Date 1597376048 14400 # Node ID c315a866dbe92961f6f2b3c7e107b8e6c6efa32e # Parent bdc53d9affb2e86ddd1609c7c9c2838952d0975a attempt to avoid apparent graphics-related crash at shutdown (bug #58814) * interpreter.cc (interpreter::shutdown): Reorder actions. Close figure windows before other actions. USe OCTAVE_SAFE_CALL for most function calls. Use feval to invoke 'close ("all")' instead of calling gh_manager::close_all_figures. Clear all variables before calling m_symbol_table.cleanup. diff -r bdc53d9affb2 -r c315a866dbe9 libinterp/corefcn/interpreter.cc --- a/libinterp/corefcn/interpreter.cc Sun Aug 02 16:16:31 2020 +0200 +++ b/libinterp/corefcn/interpreter.cc Thu Aug 13 23:34:08 2020 -0400 @@ -845,22 +845,43 @@ void interpreter::shutdown (void) { + OCTAVE_SAFE_CALL (feval, ("close", ovl ("all"), 0)); + // If we are attached to a GUI, process pending events and // disable the link. - m_event_manager.process_events (true); - m_event_manager.disable (); + OCTAVE_SAFE_CALL (m_event_manager.process_events, (true)); + OCTAVE_SAFE_CALL (m_event_manager.disable, ()); OCTAVE_SAFE_CALL (m_input_system.clear_input_event_hooks, ()); // Any atexit functions added after this function call won't be - // executed. + // executed. Each atexit function is executed with + // OCTAVE_SAFE_CALL, so we don't need that here. execute_atexit_fcns (); + // Clear all functions and variables. + + OCTAVE_SAFE_CALL (clear_all, (true)); + + // We may still have some figures. Close them. + + OCTAVE_SAFE_CALL (feval, ("close", ovl ("all"), 0)); + + // What is supposed to happen if a figure has a closerequestfcn or + // deletefcn callback registered that creates other figures or + // variables? What if those variables are classdef objects with + // destructors that can create figures? The possibilities are + // endless. At some point, we have to give up and force execution + // to end. + + OCTAVE_SAFE_CALL (clear_all, (true)); + // Do this explicitly so that destructors for mex file objects // are called, so that functions registered with mexAtExit are // called. + OCTAVE_SAFE_CALL (m_symbol_table.clear_mex_functions, ()); OCTAVE_SAFE_CALL (command_editor::restore_terminal_state, ()); @@ -870,14 +891,15 @@ if (! command_history::ignoring_entries ()) OCTAVE_SAFE_CALL (command_history::clean_up_and_save, ()); - OCTAVE_SAFE_CALL (m_gh_manager->close_all_figures, ()); - - m_gtk_manager.unload_all_toolkits (); - // FIXME: May still need something like this to ensure that // destructors for class objects will run properly. Should that be // done earlier? Before or after atexit functions are executed? - m_symbol_table.cleanup (); + // What will happen if the destructor for an obect attempts to + // display a figure? + + OCTAVE_SAFE_CALL (m_symbol_table.cleanup, ()); + + OCTAVE_SAFE_CALL (m_gtk_manager.unload_all_toolkits, ()); OCTAVE_SAFE_CALL (sysdep_cleanup, ());