From: Roland McGrath Date: Wed, 16 Sep 2009 07:39:34 +0000 (-0700) Subject: dwarfcmp: Describe context mismatch details at the end. X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a417dd336d731f8fc083c31ae485df0b555ab881;p=thirdparty%2Felfutils.git dwarfcmp: Describe context mismatch details at the end. --- diff --git a/src/ChangeLog b/src/ChangeLog index a201b1709..deb55413c 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2009-09-15 Roland McGrath + + * dwarfcmp.cc (talker, noisy_cmp): Describe context mismatch details + at the end. + 2009-08-27 Roland McGrath * dwarfcmp.cc (do_writer_test): New function, broken out of ... diff --git a/src/dwarfcmp.cc b/src/dwarfcmp.cc index 25afea9c0..37cbb6c6a 100644 --- a/src/dwarfcmp.cc +++ b/src/dwarfcmp.cc @@ -145,6 +145,24 @@ struct talker : public dwarf_ref_tracker typedef typename _base::dwarf1_die::attributes_type::const_iterator attr1; typedef typename _base::dwarf2_die::attributes_type::const_iterator attr2; + template + struct die_hasher + : public std::unary_function + { + inline dwarf::debug_info_entry::identity_type + operator () (const die &ref) const + { + return (*ref).identity (); + } + }; + + typedef std::tr1::unordered_set > die2_set; + typedef std::tr1::unordered_map > context_map; + context_map bad_context_; + + string prefix_; + const typename dwarf1::debug_info_entry *a_; const typename dwarf2::debug_info_entry *b_; bool result_; @@ -164,7 +182,9 @@ struct talker : public dwarf_ref_tracker inline ostream &location () const { - return cout << hex << a_->offset () << " vs " << b_->offset () << ": "; + return cout << prefix_ + << hex << a_->offset () << " vs " << b_->offset () + << ": "; } inline void visit (const typename dwarf1::debug_info_entry &a, @@ -284,7 +304,10 @@ struct talker : public dwarf_ref_tracker cout << " (XXX refs now equal again!)" << (cmp.equals (*ref1, *ref2) ? "" : " (and not identical!!)"); else if (cmp.equals (*ref1, *ref2)) - cout << " (identical but contexts mismatch)"; + { + cout << " (identical but contexts mismatch)"; + bad_context_[ref1].insert (ref2); + } else { _base notracker; @@ -297,6 +320,60 @@ struct talker : public dwarf_ref_tracker << ")"; } } + + inline void print_one_bad_context (const die1 &ref1, const die2 &ref2) + { + dwarf_comparator cmp (*this); + + { + ostringstream pfx; + pfx << hex << (*ref1).offset () << " vs " << (*ref2).offset () + << " context: "; + prefix_ = pfx.str (); + } + + typename subtracker::left_context_type left = left_context (ref1); + typename subtracker::right_context_type right = right_context (ref2); + + left.pop (); + right.pop (); + while (!left.empty ()) + { + if (right.empty ()) + { + cout << prefix_ + << (*left.const_top ()).offset () << " vs top-level" << endl; + return; + } + + // This prints the differences if it finds some. + visit (*left.const_top (), *right.const_top ()); + if (!visiting_result_) + { + cout << endl; + return; + } + if (!cmp.equals (a_->attributes (), b_->attributes ())) + return; + + left.pop (); + right.pop (); + } + if (!right.empty ()) + cout << prefix_ + << "top-level vs " << (*right.const_top ()).offset () << endl; + } + + inline void print_bad_context () + { + for (typename context_map::const_iterator i = bad_context_.begin (); + i != bad_context_.end (); + ++i) + for (typename die2_set::const_iterator j = i->second.begin (); + j != i->second.end (); + ++j) + print_one_bad_context (i->first, *j); + } }; template @@ -329,18 +406,16 @@ struct noisy_cmp { inline bool operator () (const dwarf1 &a, const dwarf2 &b) { - return equals (a, b) && this->_m_tracker.result_; + if (equals (a, b) && this->_m_tracker.result_) + { + assert (this->_m_tracker.bad_context_.empty ()); + return true; + } + this->_m_tracker.print_bad_context (); + return false; } }; - -template -static inline bool -noisy_compare (const dwarf1 &a, const dwarf2 &b) -{ - return noisy_cmp () (a, b); -} - template static inline bool noisy_compare (const dwarf1 &a, const dwarf2 &b, bool print_all)