[PATCH] libdw: Search for abstract origin in the correct CU
With gcc -flto the abstract origin of an inlined subroutine could be in a different CU. dwarf_getscopes might return an empty scope if it cannot find the abstract origin scope. So make sure to search in the We also tried to add the origin match in pc_record directly in the current inlined scope. This always failed, causing to do a needless traversal, followed by the full CU scan in dwarf_getscopes. Just always stop the pc_record search and then do the CU origin_match in dwarf_getscopes. Signed-off-by: Mark Wielaard --- libdw/ChangeLog| 6 + libdw/dwarf_getscopes.c| 18 -- tests/ChangeLog| 6 + tests/Makefile.am | 1 + tests/run-addr2line-i-test.sh | 43 + tests/testfile-inlines-lto.bz2 | Bin 0 -> 2838 bytes 6 files changed, 66 insertions(+), 8 deletions(-) create mode 100755 tests/testfile-inlines-lto.bz2 diff --git a/libdw/ChangeLog b/libdw/ChangeLog index 4c7af94e..71e96c88 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,9 @@ +2023-01-22 Mark Wielaard + + * dwarf_getscopes.c (pc_record): Return nscopes when done. + (dwarf_getscopes): Call __libdw_visit_scopes with + inlined_origin CU. + 2022-12-20 Mark Wielaard * Makefile.am (AM_CPPFLAGS): Add -I$(srcdir)/../libebl. diff --git a/libdw/dwarf_getscopes.c b/libdw/dwarf_getscopes.c index 5662eecf..833f1ac5 100644 --- a/libdw/dwarf_getscopes.c +++ b/libdw/dwarf_getscopes.c @@ -1,5 +1,6 @@ /* Return scope DIEs containing PC address. Copyright (C) 2005, 2007, 2015 Red Hat, Inc. + Copyright (C) 2023 Mark J. Wielaard This file is part of elfutils. This file is free software; you can redistribute it and/or modify @@ -173,12 +174,8 @@ pc_record (unsigned int depth, struct Dwarf_Die_Chain *die, void *arg) /* Not there yet. */ return 0; - /* Now we are in a scope that contains the concrete inlined instance. - Search it for the inline function's abstract definition. - If we don't find it, return to search the containing scope. - If we do find it, the nonzero return value will bail us out - of the postorder traversal. */ - return __libdw_visit_scopes (depth, die, NULL, &origin_match, NULL, a); + /* This is the innermost inline scope, we are done here. */ + return a->nscopes; } @@ -193,8 +190,13 @@ dwarf_getscopes (Dwarf_Die *cudie, Dwarf_Addr pc, Dwarf_Die **scopes) int result = __libdw_visit_scopes (0, &cu, NULL, &pc_match, &pc_record, &a); - if (result == 0 && a.scopes != NULL) -result = __libdw_visit_scopes (0, &cu, NULL, &origin_match, NULL, &a); + if (result >= 0 && a.scopes != NULL && a.inlined > 0) +{ + /* We like the find the inline function's abstract definition + scope, but that might be in a different CU. */ + cu.die = CUDIE (a.inlined_origin.cu); + result = __libdw_visit_scopes (0, &cu, NULL, &origin_match, NULL, &a); +} if (result > 0) *scopes = a.scopes; diff --git a/tests/ChangeLog b/tests/ChangeLog index 66807856..ba7c1c93 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,9 @@ +2023-01-22 Mark Wielaard + + * testfile-inlines-lto.bz2: New testfile. + * run-addr2line-i-test.sh: Add new lto inlines test. + * Makefile.am (EXTRA_DIST): Add testfile-inlines-lto.bz2. + 2023-01-19 Mark Wielaard * run-debuginfod-query-retry.sh: Use libdebuginfod.so.1 instead diff --git a/tests/Makefile.am b/tests/Makefile.am index 71b19601..393ce7b1 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -426,6 +426,7 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \ testfilenolines.bz2 test-core-lib.so.bz2 test-core.core.bz2 \ test-core.exec.bz2 run-addr2line-test.sh \ run-addr2line-i-test.sh testfile-inlines.bz2 \ +testfile-inlines-lto.bz2 \ run-addr2line-i-lex-test.sh testfile-lex-inlines.bz2 \ run-addr2line-i-demangle-test.sh run-addr2line-alt-debugpath.sh \ testfileppc32.bz2 testfileppc64.bz2 \ diff --git a/tests/run-addr2line-i-test.sh b/tests/run-addr2line-i-test.sh index d08f3cba..4f63e487 100755 --- a/tests/run-addr2line-i-test.sh +++ b/tests/run-addr2line-i-test.sh @@ -220,4 +220,47 @@ testrun_compare ${abs_top_builddir}/src/addr2line --pretty-print -a -f -i -e tes (inlined by) _Z2fuv at /tmp/x.cpp:33 EOF +# == x.cpp == +# g++ x.cpp -g -fPIC -olibx.so -shared -O0 -flto +# +# __attribute__((always_inline)) inline +# int foobar(int i) +# { +# return i + 1; +# } +# +# __attribute__((always_inline)) inline +# int fubar(int i) +# { +# return i + 1; +# } +# +# __attribute__((always_inline)) inline +# int bar(int i) +# { +# return fubar(i++); +# } +# +# __attribute__((always_inline)) inline +# int foo(int i) +# { +# return foobar(i++); +# } +# +# int fu(int i) +# { +# return foo(i++) + bar(i++); +# } + +testfiles testfile-inlines-lt
[PATCH] addr2line: -C should not try to handle optional (ignored) argument
The --demangle option takes an option (ignored) argument. Since -C is the short option of --demangle it also takes that optional argument. But that means that something like -Cfi is like -C got fi as argument, while the user expects -Cfi to be like -C -f -i. Separate the --demangle and -C options. --demangle still takes an optional (ignored) argument, but -C doesn't take any arguments so -Cfi acts the same as -fiC. Also fix --target, -b, so that it is properly ignored (and not accidentially enables demangling). Signed-off-by: Mark Wielaard --- src/ChangeLog | 5 ++ src/addr2line.c | 8 ++- tests/ChangeLog | 6 +++ tests/Makefile.am | 2 + tests/run-addr2line-C-test.sh | 91 +++ 5 files changed, 110 insertions(+), 2 deletions(-) create mode 100755 tests/run-addr2line-C-test.sh diff --git a/src/ChangeLog b/src/ChangeLog index 0490088e..915494f2 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2023-01-22 Mark Wielaard + + * addr2line.c (options): Separate --demangle and -C. + (parse_opt): Ignore 'b'. + 2023-01-10 Mark Wielaard * readelf.c (get_debug_elf_data): New function. diff --git a/src/addr2line.c b/src/addr2line.c index 7768b266..d902d791 100644 --- a/src/addr2line.c +++ b/src/addr2line.c @@ -1,6 +1,6 @@ /* Locate source files and line information for given addresses Copyright (C) 2005-2010, 2012, 2013, 2015 Red Hat, Inc. - Copyright (C) 2022 Mark J. Wielaard + Copyright (C) 2022, 2023 Mark J. Wielaard This file is part of elfutils. Written by Ulrich Drepper , 2005. @@ -71,8 +71,9 @@ static const struct argp_option options[] = { "inlines", 'i', NULL, 0, N_("Show all source locations that caused inline expansion of subroutines at the address."), 0 }, - { "demangle", 'C', "ARG", OPTION_ARG_OPTIONAL, + { "demangle", OPT_DEMANGLER, "ARG", OPTION_ARG_OPTIONAL, N_("Show demangled symbols (ARG is always ignored)"), 0 }, + { NULL, 'C', NULL, 0, N_("Show demangled symbols"), 0 }, { "pretty-print", OPT_PRETTY, NULL, 0, N_("Print all information on one line, and indent inlines"), 0 }, { "relative", OPT_RELATIVE, NULL, 0, @@ -225,7 +226,10 @@ parse_opt (int key, char *arg, struct argp_state *state) print_addresses = true; break; +/* Ignore --target=bfdname. */ case 'b': + break; + case 'C': case OPT_DEMANGLER: demangle = true; diff --git a/tests/ChangeLog b/tests/ChangeLog index 66807856..14b901b9 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,9 @@ +2023-01-19 Mark Wielaard + + * run-addr2line-C-test.sh: New test. + * Makefile.am (TESTS): Add run-addr2line-C-test.sh. + (EXTRA_DIST): Likewise. + 2023-01-19 Mark Wielaard * run-debuginfod-query-retry.sh: Use libdebuginfod.so.1 instead diff --git a/tests/Makefile.am b/tests/Makefile.am index 71b19601..fa7c30ef 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -151,6 +151,7 @@ TESTS = run-arextract.sh run-arsymtest.sh run-ar.sh newfile test-nlist \ run-readelf-variant.sh run-readelf-fat-lto.sh \ run-dwfl-report-elf-align.sh run-addr2line-test.sh \ run-dwfl-report-offline-memory.sh \ + run-addr2line-C-test.sh \ run-addr2line-i-test.sh run-addr2line-i-lex-test.sh \ run-addr2line-i-demangle-test.sh run-addr2line-alt-debugpath.sh \ run-varlocs.sh run-exprlocs.sh run-varlocs-vars.sh run-funcretval.sh \ @@ -425,6 +426,7 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \ testfile-dwfl-report-elf-align-shlib.so.bz2 \ testfilenolines.bz2 test-core-lib.so.bz2 test-core.core.bz2 \ test-core.exec.bz2 run-addr2line-test.sh \ +run-addr2line-C-test.sh \ run-addr2line-i-test.sh testfile-inlines.bz2 \ run-addr2line-i-lex-test.sh testfile-lex-inlines.bz2 \ run-addr2line-i-demangle-test.sh run-addr2line-alt-debugpath.sh \ diff --git a/tests/run-addr2line-C-test.sh b/tests/run-addr2line-C-test.sh new file mode 100755 index ..8c63d78d --- /dev/null +++ b/tests/run-addr2line-C-test.sh @@ -0,0 +1,91 @@ +#! /bin/sh +# Copyright (C) 2013 Red Hat, Inc. +# Copyright (C) 2023 Mark J. Wielaard +# This file is part of elfutils. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# elfutils is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see