From: Petr Machata Date: Tue, 5 Apr 2011 15:55:30 +0000 (+0200) Subject: dwarflint: Guard against exceptions in per-DIE checks X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ff04d1e60c7cb4c6af644631ab7296333fd520b6;p=thirdparty%2Felfutils.git dwarflint: Guard against exceptions in per-DIE checks - throwing check_base::unscheduled can be used to turn off the per-DIE check for this file --- diff --git a/dwarflint/check_die_tree.cc b/dwarflint/check_die_tree.cc index e37fb8934..96f1bab52 100644 --- a/dwarflint/check_die_tree.cc +++ b/dwarflint/check_die_tree.cc @@ -38,10 +38,12 @@ class die_check_context : protected std::vector { typedef std::vector _super_t; + checkdescriptor const *_m_cd; public: die_check_context (checkdescriptor const *cd, dwarflint &lint, die_check_registrar const ®istrar) + : _m_cd (cd) { // For per-DIE runs, we are only interested in limited context: // the main iteration check, and the per-DIE check. This should @@ -63,11 +65,54 @@ public: } } + void + error (all_dies_iterator const &a_d_it, + char const *reason = NULL) + { + std::string r; + if (reason) + { + r += ": "; + r += reason; + } + + wr_error (to_where (*a_d_it)) + << "A check failed: " << (_m_cd->name () ?: "(nil)") + << r << std::endl; + } + void die (all_dies_iterator const &a_d_it) { for (iterator it = begin (); it != end (); ++it) - (*it)->die (a_d_it); + again: + try + { + (*it)->die (a_d_it); + } + catch (check_base::unscheduled &e) + { + // Turn the check off. + size_t pos = it - begin (); + delete *it; + erase (it); + it = begin () + pos; + if (it == end ()) + break; + goto again; + } + catch (check_base::failed &e) + { + // The check was supposed to emit an error message. + } + catch (std::exception &e) + { + error (a_d_it, e.what ()); + } + catch (...) + { + error (a_d_it); + } } ~die_check_context () @@ -80,7 +125,6 @@ public: check_die_tree::check_die_tree (checkstack &stack, dwarflint &lint) : highlevel_check (stack, lint) { - //std::cout << "check_die_tree" << std::endl; die_check_context ctx (descriptor (), lint, *dwarflint::die_registrar ()); for (all_dies_iterator it = all_dies_iterator (dw); diff --git a/dwarflint/highlevel_check.hh b/dwarflint/highlevel_check.hh index 3db9f5c76..ddeb9e293 100644 --- a/dwarflint/highlevel_check.hh +++ b/dwarflint/highlevel_check.hh @@ -60,7 +60,7 @@ class highlevel_check public: static checkdescriptor const *descriptor () { static checkdescriptor cd - (checkdescriptor::create ("open_highlevel_dwarf") + (checkdescriptor::create ("highlevel_check") .prereq ()); return &cd; }