Created attachment 13659 [details] compressed library file libabigail version: https://android.googlesource.com/platform/external/libabigail/+/4e975fe2bc039f3354fd7bb3df0ea9ed289fda40 This corresponds roughly to current master 190350a35f842574cf15b9a98f1ccbc3aa31a840. However, there are some minor differences. None currently in the XML writer or IR. $ git diff --stat aosp/upstream-master HEAD include src tools include/abg-comparison.h | 6 + include/abg-version.h | 8 + src/abg-comparison-priv.h | 2 + src/abg-comparison.cc | 16 ++ src/abg-config.cc | 9 + src/abg-leaf-reporter.cc | 55 ++++- src/abg-reader.cc | 54 ++-- src/abg-reporter-priv.cc | 88 ++----- src/abg-reporter-priv.h | 2 +- src/abg-tools-utils.cc | 11 +- tools/Makefile.am | 8 +- tools/abidiff.cc | 9 +- tools/abitidy.cc | 1428 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 13 files changed, 1577 insertions(+), 119 deletions(-) More significantly, abidw and its dependencies are compiled within a standardised Android build environment (Clang, compile flags, libc++ etc.). With the attached file, libc.so, about 4% of abidw libc.so --out-file /dev/null invocations result in an infinite loop. The line <class-decl name='DIR' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-1114'/> is emitted in a tight loop.
Stack trace from attaching GDB: #0 __memcmp_avx2_movbe () at ../sysdeps/x86_64/multiarch/memcmp-avx2-movbe.S:66 #1 0x00005637c946e4a5 in std::__1::char_traits<char>::compare (__s1=0x5637ccb99550 "bionic/libc/upstream-freebsd/lib/libc/gen/glob.c", __s2=0x5637ccb99550 "bionic/libc/upstream-freebsd/lib/libc/gen/glob.c", __n=48) at external/libcxx/include/__string:250 #2 std::__1::operator==<std::__1::allocator<char> > (__lhs=..., __rhs=...) at external/libcxx/include/string:3866 #3 0x00005637c9570157 in abigail::xml_writer::referenced_type_should_be_emitted (t=0x5637ccbb24b0, ctxt=..., tu=..., tu_is_last=false) at external/libabigail/src/abg-writer.cc:2267 #4 abigail::xml_writer::write_translation_unit (ctxt=..., tu=..., indent=<optimized out>, is_last=false) at external/libabigail/src/abg-writer.cc:2457 #5 0x00005637c9573700 in abigail::xml_writer::write_corpus (ctxt=..., corpus=..., indent=0, member_of_group=<optimized out>) at external/libabigail/src/abg-writer.cc:4508 #6 0x00005637c937bc7a in load_corpus_and_write_abixml (argv=0x7ffc078e0298, env=..., context=..., opts=...) at external/libabigail/tools/abidw.cc:654 #7 0x00005637c937a491 in main (argc=<optimized out>, argv=0x7ffc078e0298) at external/libabigail/tools/abidw.cc:893
Bisected to "Bug 27995 - Self comparison error from abixml file".
Hello, I couldn't reproduce this issue on the branch you mentioned, while compiling libabigail with gcc. However, I tried punching in the dark a little bit. Could you please try this patch and see if it as an impact at all? diff --git a/src/abg-writer.cc b/src/abg-writer.cc index 9f48dc92..46b6d456 100644 --- a/src/abg-writer.cc +++ b/src/abg-writer.cc @@ -2356,7 +2356,8 @@ write_translation_unit(write_context& ctxt, // considered "opaque". if (class_decl_sptr class_type = is_class_type(t)) if (class_type->get_is_declaration_only() - && !ctxt.type_is_emitted(class_type)) + && !ctxt.type_is_emitted(class_type) + && !ctxt.decl_only_type_is_emitted(class_type)) write_type(class_type, ctxt, indent + c.get_xml_element_indent()); continue;
Hmmh, actually, this one might be the one to try, rather: diff --git a/src/abg-writer.cc b/src/abg-writer.cc index 9f48dc92..2062c326 100644 --- a/src/abg-writer.cc +++ b/src/abg-writer.cc @@ -2356,7 +2356,8 @@ write_translation_unit(write_context& ctxt, // considered "opaque". if (class_decl_sptr class_type = is_class_type(t)) if (class_type->get_is_declaration_only() - && !ctxt.type_is_emitted(class_type)) + && !ctxt.type_is_emitted(class_type) + && !ctxt.decl_only_type_is_emitted(class_type)) write_type(class_type, ctxt, indent + c.get_xml_element_indent()); continue; @@ -2420,7 +2421,8 @@ write_translation_unit(write_context& ctxt, // We handle types which have declarations *and* function // types here. type_base_sptr t(*i, noop_deleter()); - if (!ctxt.type_is_emitted(t)) + if (!ctxt.type_is_emitted(t) + && !ctxt.decl_only_type_is_emitted(t)) { if (decl_base* d = get_type_declaration(*i)) {
FTR, the patches in comments #3 and #4 did not help. I have been able to reproduce *a* problem if not *the* problem using a vanilla GCC build. See https://sourceware.org/pipermail/libabigail/2021q3/003667.html.
I've debugged the issue I see with the test suite (with the debugging patches I posted active). The triggering command is: build/tools/abipkgdiff --verbose --self-check --d1 tests/data/test-diff-pkg/nmap-debuginfo-7.70-5.el8_testjcc.x86_64.rpm --d2 tests/data/test-diff-pkg/nmap-debuginfo-7.70-5.el8_testjcc.x86_64.rpm tests/data/test-diff-pkg/nmap-7.70-5.el8_testjcc.x86_64.rpm tests/data/test-diff-pkg/nmap-7.70-5.el8_testjcc.x86_64.rpm It triggers on "struct lua_State". The type already in the map (already emitted) is declaration only with no named_definition_of_declaration while the other is a canonical type (get_naked_canonical_type gives the same pointer). Tracing through what the deep_ptr_eq_functor does: The first type is a class_decl, as is the second, and end we up in equals(class_decl, class_decl). One of them is declaration only, so this function delegates to equals(class_or_union, class_or_union). One of the types is declaration only, neither are anonymous and ODR is relevant, so equality checks the scoped names. The scoped names are identical and equality evaluates to true. On the other hand, the hash values are completely different.