# HG changeset patch # User John W. Eaton # Date 1322731606 18000 # Node ID c93b953f7d54306be76072cf40d4d5fc0869f155 # Parent 3b5afcec526b49bf97af5c5e900fb2ae635720f9 plug some memory leaks * oct-parse.yy, parse.h (cleanup_statement_list): New function. * toplev.cc (main_loop): Put cleanup_statement_list on the unwind_protect stack to delete the command list created by the parser instead of deleting it directly. * oct-parse.yy (parse_fcn_file, eval_string): Likewise. * input.cc (get_debug_input): Likewise. * pt-loop.cc (tree_simple_for_command::~tree_simple_for_command, tree_complex_for_command::~tree_complex_for_command): Also delete lhs expression. * pt-idx.cc (tree_index_expression::~tree_index_expression): Also delete contents of dyn_field list. diff -r 3b5afcec526b -r c93b953f7d54 src/input.cc --- a/src/input.cc Thu Dec 01 04:04:50 2011 -0500 +++ b/src/input.cc Thu Dec 01 04:26:46 2011 -0500 @@ -749,17 +749,15 @@ if (retval == 0 && global_command) { - global_command->accept (*current_evaluator); + unwind_protect inner_frame; - // FIXME -- To avoid a memory leak, global_command should be - // deleted, I think. But doing that here causes trouble if - // an error occurs while executing a debugging command - // (dbstep, for example). It's not clear to me why that - // happens. - // - // delete global_command; - // - // global_command = 0; + // Use an unwind-protect cleanup function so that the + // global_command list will be deleted in the event of an + // interrupt. + + inner_frame.add_fcn (cleanup_statement_list, &global_command); + + global_command->accept (*current_evaluator); if (octave_completion_matches_called) octave_completion_matches_called = false; diff -r 3b5afcec526b -r c93b953f7d54 src/oct-parse.yy --- a/src/oct-parse.yy Thu Dec 01 04:04:50 2011 -0500 +++ b/src/oct-parse.yy Thu Dec 01 04:26:46 2011 -0500 @@ -3565,7 +3565,11 @@ int status = yyparse (); - delete global_command; + // Use an unwind-protect cleanup function so that the + // global_command list will be deleted in the event of an + // interrupt. + + frame.add_fcn (cleanup_statement_list, &global_command); fcn_ptr = primary_fcn_ptr; @@ -4345,6 +4349,14 @@ { if (command_list) { + unwind_protect inner_frame; + + // Use an unwind-protect cleanup function so that the + // global_command list will be deleted in the event of an + // interrupt. + + inner_frame.add_fcn (cleanup_statement_list, &command_list); + tree_statement *stmt = 0; if (command_list->length () == 1 @@ -4381,10 +4393,6 @@ else error ("eval: invalid use of statement list"); - delete command_list; - - command_list = 0; - if (error_state || tree_return_command::returning || tree_break_command::breaking @@ -4428,6 +4436,16 @@ return eval_string (s, silent, parse_status, nargout); } +void +cleanup_statement_list (tree_statement_list **lst) +{ + if (*lst) + { + delete *lst; + *lst = 0; + } +} + DEFUN (eval, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} eval (@var{try}, @var{catch})\n\ diff -r 3b5afcec526b -r c93b953f7d54 src/parse.h --- a/src/parse.h Thu Dec 01 04:04:50 2011 -0500 +++ b/src/parse.h Thu Dec 01 04:26:46 2011 -0500 @@ -36,6 +36,7 @@ class tree; class tree_matrix; class tree_identifier; +class tree_statement_list; class octave_function; #include "oct-obj.h" @@ -113,4 +114,6 @@ extern OCTINTERP_API octave_value eval_string (const std::string&, bool silent, int& parse_status); +extern OCTINTERP_API void cleanup_statement_list (tree_statement_list **lst); + #endif diff -r 3b5afcec526b -r c93b953f7d54 src/pt-idx.cc --- a/src/pt-idx.cc Thu Dec 01 04:04:50 2011 -0500 +++ b/src/pt-idx.cc Thu Dec 01 04:26:46 2011 -0500 @@ -113,6 +113,13 @@ delete *p; args.erase (p); } + + while (! dyn_field.empty ()) + { + std::list::iterator p = dyn_field.begin (); + delete *p; + dyn_field.erase (p); + } } bool diff -r 3b5afcec526b -r c93b953f7d54 src/pt-loop.cc --- a/src/pt-loop.cc Thu Dec 01 04:04:50 2011 -0500 +++ b/src/pt-loop.cc Thu Dec 01 04:26:46 2011 -0500 @@ -91,6 +91,7 @@ tree_simple_for_command::~tree_simple_for_command (void) { + delete lhs; delete expr; delete maxproc; delete list; @@ -119,6 +120,7 @@ tree_complex_for_command::~tree_complex_for_command (void) { + delete lhs; delete expr; delete list; delete lead_comm; diff -r 3b5afcec526b -r c93b953f7d54 src/toplev.cc --- a/src/toplev.cc Thu Dec 01 04:04:50 2011 -0500 +++ b/src/toplev.cc Thu Dec 01 04:26:46 2011 -0500 @@ -571,11 +571,13 @@ { if (global_command) { - global_command->accept (*current_evaluator); + // Use an unwind-protect cleanup function so that the + // global_command list will be deleted in the event of + // an interrupt. - delete global_command; + frame.add_fcn (cleanup_statement_list, &global_command); - global_command = 0; + global_command->accept (*current_evaluator); octave_quit ();