[PATCH v2 09/10] rtemstoolkit/elf, files: Catch exceptions in destructors.

Chris Johns chrisj at rtems.org
Tue May 8 05:09:46 UTC 2018


Catch exceptions in destructures and print a message to avoid
an unhandled exception happening in an exception stack unwind.
---
 rtemstoolkit/rld-elf.cpp   | 57 ++++++++++++++++++++++--------------
 rtemstoolkit/rld-files.cpp | 72 ++++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 101 insertions(+), 28 deletions(-)

diff --git a/rtemstoolkit/rld-elf.cpp b/rtemstoolkit/rld-elf.cpp
index 60ba484..ace3967 100644
--- a/rtemstoolkit/rld-elf.cpp
+++ b/rtemstoolkit/rld-elf.cpp
@@ -435,7 +435,21 @@ namespace rld
 
     file::~file ()
     {
-      end ();
+      try
+      {
+        end ();
+      }
+      catch (rld::error re)
+      {
+        std::cerr << "error: rld::elf::file::~file: "
+                  << re.where << ": " << re.what
+                  << std::endl;
+      }
+      catch (...)
+      {
+        std::cerr << "error: rld::elf::file::~file: unhandled exception"
+                  << std::endl;
+      }
     }
 
     void
@@ -447,7 +461,8 @@ namespace rld
     void
     file::reference_release ()
     {
-      --refs;
+      if (refs > 0)
+        --refs;
     }
 
     void
@@ -525,16 +540,14 @@ namespace rld
       if (archive_ && (ek != ELF_K_ELF))
         throw rld::error ("File format in archive not ELF",
                           "elf:file:begin: " + name__);
+
+      if (ek == ELF_K_AR)
+        archive = true;
+      else if (ek == ELF_K_ELF)
+        archive = false;
       else
-      {
-        if (ek == ELF_K_AR)
-          archive = true;
-        else if (ek == ELF_K_ELF)
-          archive = false;
-        else
-          throw rld::error ("File format not ELF or archive",
-                            "elf:file:begin: " + name__);
-      }
+        throw rld::error ("File format not ELF or archive",
+                          "elf:file:begin: " + name__);
 
       if (!writable_)
       {
@@ -545,7 +558,7 @@ namespace rld
         if (ek == ELF_K_ELF)
         {
           oclass = ::gelf_getclass (elf__);
-          ident_str = elf_getident (elf__, &ident_size);
+          ident_str = ::elf_getident (elf__, &ident_size);
         }
       }
 
@@ -567,15 +580,6 @@ namespace rld
       if (refs > 0)
         throw rld::error ("References still held", "elf:file:end: " + name_);
 
-      if (elf_)
-      {
-        if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG)
-          std::cout << "libelf::end: " << elf_
-                    << ' ' << name_ << std::endl;
-        ::elf_end (elf_);
-        elf_ = 0;
-      }
-
       if (fd_ >= 0)
       {
         if (!writable)
@@ -595,12 +599,21 @@ namespace rld
         fd_ = -1;
         name_.clear ();
         archive = false;
-        elf_ = 0;
         oclass = 0;
         ident_str = 0;
         ident_size = 0;
         writable = false;
+
         secs.clear ();
+
+        if (elf_)
+        {
+          if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG)
+            std::cout << "libelf::end: " << elf_
+                      << ' ' << name_ << std::endl;
+          ::elf_end (elf_);
+          elf_ = 0;
+        }
       }
     }
 
diff --git a/rtemstoolkit/rld-files.cpp b/rtemstoolkit/rld-files.cpp
index fdf12a6..f26aeec 100644
--- a/rtemstoolkit/rld-files.cpp
+++ b/rtemstoolkit/rld-files.cpp
@@ -256,10 +256,12 @@ namespace rld
     image::~image ()
     {
       if (references_)
-	std::cerr << "rtl:file:image: references when destructing";
+	std::cerr << "rtl:file:image: references when destructing" << std::endl;
+
       if (fd_ >= 0)
       {
         ::close (fd_);
+        fd_= -1;
         if (writable && remove)
         {
           if (rld::verbose () >= RLD_VERBOSE_INFO)
@@ -268,6 +270,22 @@ namespace rld
           ::unlink (name_.path ().c_str ());
         }
       }
+
+      try
+      {
+        elf_.end ();
+      }
+      catch (rld::error re)
+      {
+        std::cerr << "error: rld::files::image:::~image: "
+                  << re.where << ": " << re.what
+                  << std::endl;
+      }
+      catch (...)
+      {
+        std::cerr << "error: rld::files::image:::~image: unhandled exception"
+                  << std::endl;
+      }
     }
 
     void
@@ -537,8 +555,22 @@ namespace rld
 
     archive::~archive ()
     {
-      end ();
-      close ();
+      try
+      {
+        end ();
+        close ();
+      }
+      catch (rld::error re)
+      {
+        std::cerr << "error: rld::files::archive::~archive: "
+                  << re.where << ": " << re.what
+                  << std::endl;
+      }
+      catch (...)
+      {
+        std::cerr << "error: rld::files::archive::~archive: unhandled exception"
+                  << std::endl;
+      }
     }
 
     void
@@ -960,8 +992,22 @@ namespace rld
 
     object::~object ()
     {
-      end ();
-      close ();
+      try
+      {
+        end ();
+        close ();
+      }
+      catch (rld::error re)
+      {
+        std::cerr << "error: rld::files::object::~object: "
+                  << re.where << ": " << re.what
+                  << std::endl;
+      }
+      catch (...)
+      {
+        std::cerr << "error: rld::files::object::~object: unhandled exception"
+                  << std::endl;
+      }
     }
 
     void
@@ -1318,7 +1364,21 @@ namespace rld
 
     cache::~cache ()
     {
-      close ();
+      try
+      {
+        close ();
+      }
+      catch (rld::error re)
+      {
+        std::cerr << "error: rld::files:cache::~cache: "
+                  << re.where << ": " << re.what
+                  << std::endl;
+      }
+      catch (...)
+      {
+        std::cerr << "error: rld::files::cache::~cache: unhandled exception"
+                  << std::endl;
+      }
     }
 
     void
-- 
2.15.1




More information about the devel mailing list