]> sourceware.org Git - libabigail.git/commitdiff
abidw, dwarf-reader: Add an option to debug DIE canonicalization
authorDodji Seketeli <dodji@redhat.com>
Thu, 31 Mar 2022 16:31:01 +0000 (18:31 +0200)
committerDodji Seketeli <dodji@redhat.com>
Mon, 20 Jun 2022 15:19:27 +0000 (17:19 +0200)
While looking at something else, it appeared that I needed an option
to turn on checks to debug DIE canonicalization.  That option would
itself be enable only when the project is configured using the
--enable-debug-type-canonicalization configure option.

* include/abg-ir.h
(environment::debug_die_canonicalization_is_on): Declare new methods.
* src/abg-ir.cc (environment::debug_die_canonicalization_is_on):
Define them.
* src/abg-dwarf-reader.cc
(compare_dies_during_canonicalization): Define new static
function.
(read_context::{debug_die_canonicalization_is_on_,
use_canonical_die_comparison_}): Declare these data members.
(read_context::read_context): Initialize them.
(read_context::get_canonical_die): When ODR is considered, if DIE
canonicalization debugging is on, use the new
compare_dies_during_canonicalization for the type comparison to be
done both structurally and canonically; both comparison should
yield the same result.  Also, make this method function non-const.
* src/abg-ir-priv.h
(environment::priv::debug_die_canonicalization_): Define new data
member.
(environment::priv::priv): Initialize it.
* tools/abidw.cc (options::debug_die_canonicalization_): Define
new data member.
(options::options): Initialize it.
(display_usage): Add a description for the --debug-dc option.
(parse_command): Parse the new --debug-dc option.
(load_corpus_and_write_abixml): Use the new
environment::debug_die_canonicalization_is_on.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
include/abg-ir.h
src/abg-dwarf-reader.cc
src/abg-ir-priv.h
src/abg-ir.cc
tools/abidw.cc

index a2f4e1a7cb86b4937c6da77b7a347891482a469c..3ca4d0a8a4d1f22cc04558d47953e7977d133d77 100644 (file)
@@ -217,6 +217,12 @@ public:
 
   bool
   debug_type_canonicalization_is_on() const;
+
+  void
+  debug_die_canonicalization_is_on(bool flag);
+
+  bool
+  debug_die_canonicalization_is_on() const;
 #endif
 
   vector<type_base_sptr>* get_canonical_types(const char* name);
index 27dd4fafe26d58c07d8c8dea2475ef44015f5402..d43364f17fa7c21311aae25ebd9e4a2cecf59591 100644 (file)
@@ -541,6 +541,10 @@ compare_dies(const read_context& ctxt,
             const Dwarf_Die *l, const Dwarf_Die *r,
             bool update_canonical_dies_on_the_fly);
 
+static bool
+compare_dies_during_canonicalization(read_context& ctxt,
+                                    const Dwarf_Die *l, const Dwarf_Die *r,
+                                    bool update_canonical_dies_on_the_fly);
 
 /// Find the file name of the alternate debug info file.
 ///
@@ -2136,6 +2140,10 @@ public:
   corpus::exported_decls_builder* exported_decls_builder_;
   options_type                 options_;
   bool                         drop_undefined_syms_;
+#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
+  bool                         debug_die_canonicalization_is_on_;
+  bool                         use_canonical_die_comparison_;
+#endif
   read_context();
 
 private:
@@ -2279,6 +2287,11 @@ public:
     options_.load_in_linux_kernel_mode = linux_kernel_mode;
     options_.load_all_types = load_all_types;
     drop_undefined_syms_ = false;
+#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
+    debug_die_canonicalization_is_on_ =
+      environment->debug_die_canonicalization_is_on();
+    use_canonical_die_comparison_ = true;
+#endif
     load_in_linux_kernel_mode(linux_kernel_mode);
   }
 
@@ -2861,7 +2874,7 @@ public:
   get_canonical_die(const Dwarf_Die *die,
                    Dwarf_Die &canonical_die,
                    size_t where,
-                   bool die_as_type) const
+                   bool die_as_type)
   {
     const die_source source = get_die_source(die);
 
@@ -2915,6 +2928,29 @@ public:
        // ABG_ASSERT(i->second.size() == 1);
        Dwarf_Off canonical_die_offset = i->second.front();
        get_die_from_offset(source, canonical_die_offset, &canonical_die);
+#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
+  if (debug_die_canonicalization_is_on_)
+    {
+      use_canonical_die_comparison_ = false;
+      bool structural_equality =
+       compare_dies(*this, &canonical_die, die,
+                    /*update_canonical_dies_on_the_fly=*/false);
+      use_canonical_die_comparison_ = true;
+      if (!structural_equality)
+       {
+         std::cerr << "structural & canonical equality different for DIEs: "
+                   << std::hex
+                   << "l: " << canonical_die_offset
+                   << ", r: " << die_offset
+                   << std::dec
+                   << ", repr: '"
+                   << get_die_pretty_type_representation(&canonical_die, 0)
+                   << "'"
+                   << std::endl;
+         ABG_ASSERT_NOT_REACHED;
+       }
+    }
+#endif
        set_canonical_die_offset(canonical_dies,
                                 die_offset,
                                 canonical_die_offset);
@@ -2929,8 +2965,9 @@ public:
        cur_die_offset = *o;
        get_die_from_offset(source, cur_die_offset, &canonical_die);
        // compare die and canonical_die.
-       if (compare_dies(*this, die, &canonical_die,
-                        /*update_canonical_dies_on_the_fly=*/true))
+       if (compare_dies_during_canonicalization(const_cast<read_context&>(*this),
+                                                die, &canonical_die,
+                                                /*update_canonical_dies_on_the_fly=*/true))
          {
            set_canonical_die_offset(canonical_dies,
                                     die_offset,
@@ -3049,8 +3086,9 @@ public:
        Dwarf_Off die_offset = i->second[n];
        get_die_from_offset(source, die_offset, &canonical_die);
        // compare die and canonical_die.
-       if (compare_dies(*this, die, &canonical_die,
-                        /*update_canonical_dies_on_the_fly=*/true))
+       if (compare_dies_during_canonicalization(const_cast<read_context&>(*this),
+                                                die, &canonical_die,
+                                                /*update_canonical_dies_on_the_fly=*/true))
          {
            set_canonical_die_offset(canonical_dies,
                                     initial_die_offset,
@@ -10745,6 +10783,60 @@ compare_dies(const read_context& ctxt,
                      update_canonical_dies_on_the_fly);
 }
 
+/// Compare two DIEs for the purpose of canonicalization.
+///
+/// This is a sub-routine of read_context::get_canonical_die.
+///
+/// When DIE canonicalization debugging is on, this function performs
+/// both structural and canonical comparison.  It expects that both
+/// comparison yield the same result.
+///
+/// @param ctxt the read context.
+///
+/// @param l the left-hand-side comparison operand DIE.
+///
+/// @param r the right-hand-side comparison operand DIE.
+///
+/// @param update_canonical_dies_on_the_fly if true, then some
+/// aggregate DIEs will see their canonical types propagated.
+///
+/// @return true iff @p l equals @p r.
+static bool
+compare_dies_during_canonicalization(read_context& ctxt,
+                                    const Dwarf_Die *l,
+                                    const Dwarf_Die *r,
+                                    bool update_canonical_dies_on_the_fly)
+{
+#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
+  if (ctxt.debug_die_canonicalization_is_on_)
+    {
+      bool canonical_equality = false, structural_equality = false;
+      ctxt.use_canonical_die_comparison_ = false;
+      structural_equality = compare_dies(ctxt, l, r,
+                                        /*update_canonical_dies_on_the_fly=*/false);
+      ctxt.use_canonical_die_comparison_ = true;
+      canonical_equality = compare_dies(ctxt, l, r,
+                                       update_canonical_dies_on_the_fly);
+      if (canonical_equality != structural_equality)
+       {
+         std::cerr << "structural & canonical equality different for DIEs: "
+                   << std::hex
+                   << "l: " << dwarf_dieoffset(const_cast<Dwarf_Die*>(l))
+                   << ", r: " << dwarf_dieoffset(const_cast<Dwarf_Die*>(r))
+                   << std::dec
+                   << ", repr: '"
+                   << ctxt.get_die_pretty_type_representation(l, 0)
+                   << "'"
+                   << std::endl;
+         ABG_ASSERT_NOT_REACHED;
+       }
+      return structural_equality;
+    }
+#endif
+  return compare_dies(ctxt, l, r,
+                     update_canonical_dies_on_the_fly);
+}
+
 // ----------------------------------
 // </die comparison engine>
 // ---------------------------------
index a01a1b2cd5f008762bc73db1e0c5fd240066e373..f04266a8c9890566fffa78b138c05c0b32fdb84c 100644 (file)
@@ -403,6 +403,7 @@ struct environment::priv
   // result, otherwise, canonicalization is "broken" for that
   // particular type.
   bool                                 debug_type_canonicalization_;
+  bool                                 debug_die_canonicalization_;
 #endif
 
   priv()
@@ -417,7 +418,8 @@ struct environment::priv
 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
     ,
       use_canonical_type_comparison_(true),
-      debug_type_canonicalization_(false)
+      debug_type_canonicalization_(false),
+      debug_die_canonicalization_(false)
 #endif
   {}
 
index 717c195d6912982b6f35032b5d33584c26c06d3f..bdeec16222c1ccd34f363bc117dc5628a194c4fd 100644 (file)
@@ -3652,6 +3652,24 @@ environment::debug_type_canonicalization_is_on(bool flag)
 bool
 environment::debug_type_canonicalization_is_on() const
 {return priv_->debug_type_canonicalization_;}
+
+/// Setter of the "DIE canonicalization debugging" mode, triggered by
+/// using the command: "abidw --debug-dc".
+///
+/// @param flag true iff the DIE canonicalization debugging mode is
+/// enabled.
+void
+environment::debug_die_canonicalization_is_on(bool flag)
+{priv_->debug_die_canonicalization_ = flag;}
+
+/// Getter of the "DIE canonicalization debugging" mode, triggered by
+/// using the command: "abidw --debug-dc".
+///
+/// @return true iff the DIE canonicalization debugging mode is
+/// enabled.
+bool
+environment::debug_die_canonicalization_is_on() const
+{return priv_->debug_die_canonicalization_;}
 #endif // WITH_DEBUG_TYPE_CANONICALIZATION
 
 /// Get the vector of canonical types which have a given "string
index 1ca642bb294b8ee2db00b1c21329d02a4b56e0c1..174f084aca79aca014636ca2fea50a27b90beae1 100644 (file)
@@ -108,6 +108,7 @@ struct options
 #endif
 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
   bool                 debug_type_canonicalization;
+  bool                 debug_die_canonicalization;
 #endif
   bool                 annotate;
   bool                 do_log;
@@ -145,6 +146,7 @@ struct options
 #endif
 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
       debug_type_canonicalization(),
+      debug_die_canonicalization(),
 #endif
       annotate(),
       do_log(),
@@ -212,6 +214,7 @@ display_usage(const string& prog_name, ostream& out)
 #endif
 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
     << "  --debug-tc  debug the type canonicalization process\n"
+    << "  --debug-dc  debug the DIE canonicalization process\n"
 #endif
 #ifdef WITH_CTF
     << "  --ctf use CTF instead of DWARF in ELF files\n"
@@ -380,6 +383,9 @@ parse_command_line(int argc, char* argv[], options& opts)
       else if (!strcmp(argv[i], "--debug-tc")
               || !strcmp(argv[i], "debug-type-canonicalization"))
        opts.debug_type_canonicalization = true;
+      else if (!strcmp(argv[i], "--debug-dc")
+              || !strcmp(argv[i], "debug-die-canonicalization"))
+       opts.debug_die_canonicalization = true;
 #endif
       else if (!strcmp(argv[i], "--annotate"))
        opts.annotate = true;
@@ -530,6 +536,8 @@ load_corpus_and_write_abixml(char* argv[],
 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
   if (opts.debug_type_canonicalization)
     env->debug_type_canonicalization_is_on(true);
+  if (opts.debug_die_canonicalization)
+    env->debug_die_canonicalization_is_on(true);
 #endif
 
   // First of all, read a libabigail IR corpus from the file specified
This page took 0.068872 seconds and 5 git commands to generate.