Index: plugin.cc =================================================================== RCS file: /cvs/src/src/gold/plugin.cc,v retrieving revision 1.22 diff -u -p -r1.22 plugin.cc --- plugin.cc 12 Oct 2009 06:02:06 -0000 1.22 +++ plugin.cc 28 Oct 2009 00:56:20 -0000 @@ -238,8 +238,14 @@ Plugin::all_symbols_read() inline void Plugin::cleanup() { - if (this->cleanup_handler_ != NULL) - (*this->cleanup_handler_)(); + if (this->cleanup_handler_ != NULL && !this->cleanup_done_) + { + // Set this flag before calling to prevent a recursive plunge + // in the event that a plugin's cleanup handler issues a + // fatal error. + this->cleanup_done_ = true; + (*this->cleanup_handler_)(); + } } // Plugin_manager methods. @@ -350,13 +356,10 @@ Plugin_manager::layout_deferred_objects( void Plugin_manager::cleanup() { - if (this->cleanup_done_) - return; for (this->current_ = this->plugins_.begin(); this->current_ != this->plugins_.end(); ++this->current_) (*this->current_)->cleanup(); - this->cleanup_done_ = true; } // Make a new Pluginobj object. This is called when the plugin calls @@ -423,8 +426,8 @@ Plugin_manager::add_input_file(char *pat Task_token* next_blocker = new Task_token(true); next_blocker->add_blocker(); if (this->layout_->incremental_inputs()) - gold_error(_("Input files added by plug-ins in --incremental mode not " - "supported yet.\n")); + gold_error(_("input files added by plug-ins in --incremental mode not " + "supported yet")); this->workqueue_->queue_soon(new Read_symbols(this->input_objects_, this->symtab_, this->layout_, Index: plugin.h =================================================================== RCS file: /cvs/src/src/gold/plugin.h,v retrieving revision 1.8 diff -u -p -r1.8 plugin.h --- plugin.h 6 Oct 2009 20:15:09 -0000 1.8 +++ plugin.h 28 Oct 2009 00:56:20 -0000 @@ -54,7 +54,8 @@ class Plugin args_(), claim_file_handler_(NULL), all_symbols_read_handler_(NULL), - cleanup_handler_(NULL) + cleanup_handler_(NULL), + cleanup_done_(false) { } ~Plugin() @@ -112,6 +113,8 @@ class Plugin ld_plugin_claim_file_handler claim_file_handler_; ld_plugin_all_symbols_read_handler all_symbols_read_handler_; ld_plugin_cleanup_handler cleanup_handler_; + // TRUE if the cleanup handlers have been called. + bool cleanup_done_; }; // A manager class for plugins. @@ -121,7 +124,7 @@ class Plugin_manager public: Plugin_manager(const General_options& options) : plugins_(), objects_(), deferred_layout_objects_(), input_file_(NULL), - plugin_input_file_(), in_replacement_phase_(false), cleanup_done_(false), + plugin_input_file_(), in_replacement_phase_(false), options_(options), workqueue_(NULL), task_(NULL), input_objects_(NULL), symtab_(NULL), layout_(NULL), dirpath_(NULL), mapfile_(NULL), this_blocker_(NULL) @@ -263,9 +266,6 @@ class Plugin_manager // placeholder symbols from the Pluginobj objects. bool in_replacement_phase_; - // TRUE if the cleanup handlers have been called. - bool cleanup_done_; - const General_options& options_; Workqueue* workqueue_; Task* task_;