]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
dwarflint: Guard against exceptions in per-DIE checks
authorPetr Machata <pmachata@redhat.com>
Tue, 5 Apr 2011 15:55:30 +0000 (17:55 +0200)
committerPetr Machata <pmachata@redhat.com>
Tue, 5 Apr 2011 15:55:30 +0000 (17:55 +0200)
- throwing check_base::unscheduled can be used to turn off the per-DIE
  check for this file

dwarflint/check_die_tree.cc
dwarflint/highlevel_check.hh

index e37fb8934968c950190138f3eed69c2a02711c2d..96f1bab52771cef9e1556ddc282a5de32670f25b 100644 (file)
@@ -38,10 +38,12 @@ class die_check_context
   : protected std::vector<die_check *>
 {
   typedef std::vector<die_check *> _super_t;
+  checkdescriptor const *_m_cd;
 
 public:
   die_check_context (checkdescriptor const *cd, dwarflint &lint,
                     die_check_registrar const &registrar)
+    : _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<dwarf> 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<dwarf> 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<check_die_tree> (stack, lint)
 {
-  //std::cout << "check_die_tree" << std::endl;
   die_check_context ctx (descriptor (), lint, *dwarflint::die_registrar ());
 
   for (all_dies_iterator<dwarf> it = all_dies_iterator<dwarf> (dw);
index 3db9f5c76d35c3d4c91aedb94bc57459a242e86f..ddeb9e293b98bcebb6df631a68030444e21f3c3c 100644 (file)
@@ -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<typeof (*_m_loader)> ());
     return &cd;
   }