From: Roland McGrath Date: Thu, 20 Aug 2009 08:19:17 +0000 (-0700) Subject: Add dwarfcmp -l to show all differences. X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6732e03ef2ac24a272c101324d2d6736df619554;p=thirdparty%2Felfutils.git Add dwarfcmp -l to show all differences. --- diff --git a/libdw/ChangeLog b/libdw/ChangeLog index 1b4125d53..b36935e23 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,9 @@ +2009-08-20 Roland McGrath + + * c++/dwarf_comparator: Use tracker::subtracker for subcomparator. + Let mismatch hooks return bool that is true to keep comparing. + * c++/dwarf_tracker: Define subtracker. + 2009-08-19 Roland McGrath * c++/dwarf_tracker: Revamp derived tracker logic. diff --git a/libdw/c++/dwarf_comparator b/libdw/c++/dwarf_comparator index 7ba2475c3..3e1366391 100644 --- a/libdw/c++/dwarf_comparator +++ b/libdw/c++/dwarf_comparator @@ -96,19 +96,22 @@ namespace elfutils { } - inline void mismatch (const cu1 &, const cu1 &, // at, end - const cu2 &, const cu2 &) + inline bool mismatch (cu1 &, const cu1 &, // at, end + cu2 &, const cu2 &) { + return false; } - inline void mismatch (const die1 &, const die1 &, // at, end - const die2 &, const die2 &) + inline bool mismatch (die1 &, const die1 &, // at, end + die2 &, const die2 &) { + return false; } - inline void mismatch (const attr1 &, const attr1 &, // at, end - const attr2 &, const attr2 &) + inline bool mismatch (attr1 &, const attr1 &, // at, end + attr2 &, const attr2 &) { + return false; } struct left_context_type {}; @@ -159,6 +162,7 @@ namespace elfutils inline dwarf_tracker_base () {} + typedef dwarf_tracker_base subtracker; inline dwarf_tracker_base (const dwarf_tracker_base &, reference_match &, const left_context_type &, const right_context_type &) @@ -175,6 +179,9 @@ namespace elfutils private: tracker &_m_tracker; + typedef dwarf_comparator subcomparator; + template struct matcher : public std::binary_function { @@ -207,10 +214,13 @@ namespace elfutils cu2_it it2 = b.begin (); const cu1_it end1 = a.end (); const cu2_it end2 = b.end (); - if (subr::container_equal - (it1, end1, it2, end2, MATCHER (compile_units))) - return true; - _m_tracker.mismatch (it1, end1, it2, end2); + do + { + if (subr::container_equal + (it1, end1, it2, end2, MATCHER (compile_units))) + return true; + } + while (_m_tracker.mismatch (it1, end1, it2, end2)); return false; } @@ -299,18 +309,21 @@ namespace elfutils // The set of attributes matches, in order. Compare the values. it1 = a.begin (); it2 = b.begin (); - if (subr::container_equal (it1, end1, it2, end2, match_rhs (*this))) - return true; - _m_tracker.mismatch (it1, end1, it2, end2); + do + { + if (subr::container_equal (it1, end1, it2, end2, + match_rhs (*this))) + return true; + } + while (_m_tracker.mismatch (it1, end1, it2, end2)); return false; } if (it1 != end1 && it2 != end2 && !(attributes1::ordered () && attributes2::ordered ())) { - /* We have the same number of attributes, but the names don't match. - - */ + /* We have the same number of attributes, but the names don't + match. Populate two sorted maps and compare those. */ ait1_map sorted1; populate (sorted1, a); @@ -319,18 +332,18 @@ namespace elfutils populate (sorted2, b); std::pair result + typename ait2_map::iterator> result = std::mismatch (sorted1.begin (), sorted1.end (), sorted2.begin (), match_sorted (*this)); - if (result.first == sorted1.end () && result.second == sorted2.end ()) + if (result.first == sorted1.end () + && result.second == sorted2.end ()) return true; it1 = result.first->second; it2 = result.second->second; } - _m_tracker.mismatch (it1, end1, it2, end2); - return false; + return _m_tracker.mismatch (it1, end1, it2, end2); } typedef typename dwarf1::debug_info_entry::children_type children1; @@ -368,10 +381,11 @@ namespace elfutils cit2 it2 = b.begin (); const cit1 end1 = a.end (); const cit2 end2 = b.end (); - if (subr::container_equal (it1, end1, it2, end2, - MATCHER (debug_info_entry::children_type))) - return true; - _m_tracker.mismatch (it1, end1, it2, end2); + do + if (subr::container_equal (it1, end1, it2, end2, + MATCHER (debug_info_entry::children_type))) + return true; + while (_m_tracker.mismatch (it1, end1, it2, end2)); return false; } @@ -494,8 +508,8 @@ namespace elfutils bool result = !has_children; if (has_children) { - tracker t (_m_tracker, matched, lhs, rhs); - result = dwarf_comparator (t).match (a.children (), b.children ()); + typename tracker::subtracker t (_m_tracker, matched, lhs, rhs); + result = subcomparator (t).equals (a.children (), b.children ()); } // Let the tracker cache a result for its reference_matched. diff --git a/libdw/c++/dwarf_tracker b/libdw/c++/dwarf_tracker index 23a8a6af2..acff400cd 100644 --- a/libdw/c++/dwarf_tracker +++ b/libdw/c++/dwarf_tracker @@ -567,6 +567,8 @@ namespace elfutils return *elt->first == b; } + typedef dwarf_ref_tracker subtracker; + // Share the _m_seen maps with the prototype tracker, // but start a fresh walk from the given starting point. inline dwarf_ref_tracker (const dwarf_ref_tracker &proto, reference_match &, diff --git a/src/ChangeLog b/src/ChangeLog index feecbf297..dd71bf43e 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2009-08-20 Roland McGrath + + * dwarfcmp.cc (verbose): New variable. + (options, parse_opt): Add --verbose/-l to set it. + (talker): Keep going after mismatches when verbose. + 2009-08-19 Roland McGrath Diagnose reference mismatches with more detail. diff --git a/src/dwarfcmp.cc b/src/dwarfcmp.cc index d62a2edee..14f0b118c 100644 --- a/src/dwarfcmp.cc +++ b/src/dwarfcmp.cc @@ -68,6 +68,7 @@ static const struct argp_option options[] = { { NULL, 0, NULL, 0, N_("Control options:"), 0 }, { "quiet", 'q', NULL, 0, N_("Output nothing; yield exit status only"), 0 }, + { "verbose", 'l', NULL, 0, N_("Output all differences"), 0 }, { "ignore-missing", 'i', NULL, 0, N_("Don't complain if both files have no DWARF at all"), 0 }, @@ -99,6 +100,9 @@ static bool quiet; /* Nonzero if missing DWARF is equal DWARF. */ static bool missing_ok; +/* True if we should print all differences. */ +static bool verbose; + /* Nonzero to test writer classes. */ static int test_writer; @@ -130,7 +134,7 @@ template struct talker : public dwarf_ref_tracker { typedef dwarf_tracker_base _base; - typedef dwarf_ref_tracker _tracker; + typedef dwarf_ref_tracker subtracker; typedef typename _base::cu1 cu1; typedef typename _base::cu2 cu2; typedef typename _base::die1 die1; @@ -140,19 +144,26 @@ struct talker : public dwarf_ref_tracker const typename dwarf1::debug_info_entry *a_; const typename dwarf2::debug_info_entry *b_; + bool result_; inline talker () - : a_ (NULL), b_ (NULL) + : a_ (NULL), b_ (NULL), result_ (true) {} - inline talker (const talker &proto, typename _tracker::reference_match &m, - const typename _tracker::left_context_type &l, - const typename _tracker::right_context_type &r) - : _tracker (static_cast (proto), m, l, r), + inline talker (const talker &proto, typename subtracker::reference_match &m, + const typename subtracker::left_context_type &l, + const typename subtracker::right_context_type &r) + : subtracker (static_cast (proto), m, l, r), a_ (NULL), b_ (NULL) { } + inline bool keep_going () + { + result_ = false; + return verbose; + } + inline ostream &location () const { return cout << hex << a_->offset () << " vs " << b_->offset () << ": "; @@ -169,43 +180,67 @@ struct talker : public dwarf_ref_tracker << dwarf::tags::name (b.tag ()); } - inline void mismatch (const cu1 &it1, const cu1 &end1, - const cu2 &it2, const cu2 &end2) + inline bool mismatch (cu1 &it1, const cu1 &end1, + cu2 &it2, const cu2 &end2) { if (it1 == end1) // a lacks some of b's CUs. - cout << "files differ: " - << dec << subr::length (it2, end2) - << " extra compilation units " - << endl; + { + cout << "files differ: " + << dec << subr::length (it2, end2) + << " extra compilation units " + << endl; + it2 = end2; + } else if (it2 == end2) // b lacks some of a's CUs. - cout << "files differ: " - << dec << subr::length (it1, end1) - << " compilation units missing " - << endl; - // Otherwise the differing CU will have announced itself. + { + cout << "files differ: " + << dec << subr::length (it1, end1) + << " compilation units missing " + << endl; + it1 = end1; + } + else + // Otherwise the differing CU will have announced itself. + ++it1, ++it2; + return keep_going (); } - inline void mismatch (const die1 &it1, const die1 &end1, - const die2 &it2, const die2 &end2) + inline bool mismatch (die1 &it1, const die1 &end1, + die2 &it2, const die2 &end2) { if (it1 == end1) // a_ lacks some of b_'s children. - location () << dec << subr::length (it2, end2) - << " extra children " << endl; + { + location () << dec << subr::length (it2, end2) + << " extra children " << endl; + it2 = end2; + } else if (it2 == end2) // b_ lacks some of a_'s children. - location () << dec << subr::length (it1, end1) - << " children missing " << endl; - // Otherwise the differing child will have announced itself. + { + location () << dec << subr::length (it1, end1) + << " children missing " << endl; + it1 = end1; + } + else + // Otherwise the differing child will have announced itself. + ++it1, ++it2; + return keep_going (); } - inline void mismatch (attr1 it1, const attr1 &end1, - attr2 it2, const attr2 &end2) + inline bool mismatch (attr1 &it1, const attr1 &end1, + attr2 &it2, const attr2 &end2) { if (it1 == end1) // a_ lacks some of b_'s attrs. - for (location () << " extra attributes:"; it2 != end2; ++it2) - cout << " " << to_string (*it2); + { + for (location () << " extra attributes:"; it2 != end2; ++it2) + cout << " " << to_string (*it2); + it2 = end2; + } else if (it2 == end2) // b_ lacks some of a_'s attrs. - for (location () << " missing attributes:"; it1 != end1; ++it1) - cout << " " << to_string (*it1); + { + for (location () << " missing attributes:"; it1 != end1; ++it1) + cout << " " << to_string (*it1); + it1 = end1; + } else { location () << to_string (*it1) << " vs " << to_string (*it2); @@ -213,14 +248,20 @@ struct talker : public dwarf_ref_tracker && (*it2).second.what_space () == dwarf::VS_reference) reference_mismatch ((*it1).second.reference (), (*it2).second.reference ()); + ++it1; + ++it2; } cout << endl; + return keep_going (); } inline void reference_mismatch (const die1 &ref1, const die2 &ref2) { - dwarf_comparator cmp (*(_tracker *) this); - if (cmp.equals (*ref1, *ref2)) + dwarf_comparator< + dwarf1, dwarf2, false, subtracker> cmp (*(subtracker *) this); + if (cmp.equals (ref1, ref2)) + cout << " (XXX refs now equal again!)"; + else if (cmp.equals (*ref1, *ref2)) cout << " (identical but contexts mismatch)"; else { @@ -256,7 +297,12 @@ struct quiet_cmp template struct noisy_cmp : public cmp > -{}; +{ + inline bool operator () (const dwarf1 &a, const dwarf2 &b) + { + return equals (a, b) && this->_m_tracker.result_; + } +}; // Test that one comparison works as expected. @@ -417,6 +463,10 @@ parse_opt (int key, char *, struct argp_state *) quiet = true; break; + case 'l': + verbose = true; + break; + case 'i': missing_ok = true; break;