Fix de-initialization of elf::reader::priv
authorPetr Pavlu <petr.pavlu@suse.com>
Sun, 18 Dec 2022 19:33:40 +0000 (20:33 +0100)
committerDodji Seketeli <dodji@redhat.com>
Mon, 19 Dec 2022 17:44:59 +0000 (18:44 +0100)
This fixes 7bd69830 ("Make Front Ends first class citizens").

Add a destructor for elf::reader::priv which releases any allocated alt
DWARF data and fix the initialize() method to fully reset the object.

The latter fixes a crash observed when handling multiple files. For
instance, when reading the Linux kernel tree, load_vmlinux_corpus()
processes vmlinux and all modules. Member dwarf_handle was never reset
after setting it for the first file which could later result in use of
invalid DWARF data in dwarf::reader::build_die_parent_maps().

* src/abg-elf-reader.cc (priv::~priv): Release alt debug
information.
(priv::initialize): Reset all members.
(priv::clear_alt_dwarf_debug_info_data): New helper function.

Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
src/abg-elf-reader.cc

index 3b1b5803554af23e92cf0d49b457a3ce824775af..c07f0655d471fd19bba9f3710be1439a41b4ab7f 100644 (file)
@@ -225,10 +225,10 @@ find_alt_dwarf_debug_info(Dwfl_Module *elf_module,
       // If we reach this point it means we have found the path to the
       // alternate debuginfo file and it's in alt_file_path.  So let's
       // open it and read it.
-      int fd = open(alt_file_path.c_str(), O_RDONLY);
-      if (fd == -1)
+      alt_fd = open(alt_file_path.c_str(), O_RDONLY);
+      if (alt_fd == -1)
        return result;
-      result = dwarf_begin(fd, DWARF_C_READ);
+      result = dwarf_begin(alt_fd, DWARF_C_READ);
 
 #ifdef LIBDW_HAS_DWARF_GETALT
       Dwarf_Addr bias = 0;
@@ -281,6 +281,11 @@ struct reader::priv
     initialize(debug_info_roots);
   }
 
+  ~priv()
+  {
+    clear_alt_dwarf_debug_info_data();
+  }
+
   /// Reset the private data of @elf elf::reader.
   ///
   /// @param debug_info_roots the vector of new directories where to
@@ -288,11 +293,23 @@ struct reader::priv
   void
   initialize(const vector<char**>& debug_info_roots)
   {
-    debug_info_root_paths = debug_info_roots;
+    clear_alt_dwarf_debug_info_data();
+
+    elf_handle = nullptr;
+    symtab_section = nullptr;
+    elf_architecture.clear();
+    dt_needed.clear();
     symt.reset();
+    debug_info_root_paths = debug_info_roots;
+    offline_callbacks = {};
     dwfl_handle.reset();
     elf_module = nullptr;
-    elf_handle = nullptr;
+    dwarf_handle = nullptr;
+    alt_dwarf_handle = nullptr;
+    alt_dwarf_path.clear();
+    alt_dwarf_fd = 0;
+    ctf_section = nullptr;
+    alt_ctf_section = nullptr;
   }
 
   /// Setup the necessary plumbing to open the ELF file and find all
@@ -348,6 +365,23 @@ struct reader::priv
     return result;
   }
 
+  /// Clear the resources related to the alternate DWARF data.
+  void
+  clear_alt_dwarf_debug_info_data()
+  {
+    if (alt_dwarf_fd)
+      {
+        if (alt_dwarf_handle)
+          {
+            dwarf_end(alt_dwarf_handle);
+            alt_dwarf_handle = nullptr;
+          }
+        close(alt_dwarf_fd);
+        alt_dwarf_fd = 0;
+      }
+    alt_dwarf_path.clear();
+  }
+
   /// Locate the DWARF debug info in the ELF file.
   ///
   /// This also knows how to locate split debug info.