getline can return strings with a newline as last character when reading from stdin. This could cause confusing symbol lookup failures like: addr2line: cannot find symbol 'foo ' So if the last character of the buf returned by getline is a newline just null-terminate it right there. Also add a new testcase run-addr2line-test.sh.
Signed-off-by: Mark Wielaard mjw@redhat.com --- src/ChangeLog | 5 +++ src/addr2line.c | 6 +++- tests/ChangeLog | 6 +++ tests/Makefile.am | 4 +- tests/run-addr2line-test.sh | 74 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 92 insertions(+), 3 deletions(-) create mode 100755 tests/run-addr2line-test.sh
diff --git a/src/ChangeLog b/src/ChangeLog index 051f964..eacadbc 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2013-08-12 Mark Wielaard mjw@redhat.com + + * addr2line.c (main): If there is a newline char at end of buf, + then remove it. + 2013-07-05 Mark Wielaard mjw@redhat.com
* readelf.c (print_ops): Take CU as argument, use it to print diff --git a/src/addr2line.c b/src/addr2line.c index c7e4629..f2bc325 100644 --- a/src/addr2line.c +++ b/src/addr2line.c @@ -152,11 +152,15 @@ main (int argc, char *argv[])
char *buf = NULL; size_t len = 0; + ssize_t chars; while (!feof_unlocked (stdin)) { - if (getline (&buf, &len, stdin) < 0) + if ((chars = getline (&buf, &len, stdin)) < 0) break;
+ if (buf[chars - 1] == '\n') + buf[chars - 1] = '\0'; + result = handle_address (buf, dwfl); }
diff --git a/tests/ChangeLog b/tests/ChangeLog index ea1f2de..3475d7b 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,9 @@ +2013-08-12 Mark Wielaard mjw@redhat.com + + * run-addr2line-test.sh: New test. + * Makefile.am (EXTRA_DIST): Add run-addr2line-test.sh. + (TESTS): Likewise. + 2013-07-23 Jan Kratochvil jan.kratochvil@redhat.com
* run-unstrip-n.sh (test-core.*): Ignore libc.so.6 entry and order of diff --git a/tests/Makefile.am b/tests/Makefile.am index 4fe0022..ac99e3e 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -88,7 +88,7 @@ TESTS = run-arextract.sh run-arsymtest.sh newfile test-nlist \ run-low_high_pc.sh run-macro-test.sh run-elf_cntl_gelf_getshdr.sh \ run-test-archive64.sh run-readelf-vmcoreinfo.sh \ run-readelf-mixed-corenote.sh run-dwfllines.sh \ - run-dwfl-report-elf-align.sh + run-dwfl-report-elf-align.sh run-addr2line-test.sh
if !STANDALONE check_PROGRAMS += msg_tst md5-sha1-test @@ -200,7 +200,7 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \ run-dwfllines.sh run-dwfl-report-elf-align.sh \ testfile-dwfl-report-elf-align-shlib.so.bz2 \ testfilenolines.bz2 test-core-lib.so.bz2 test-core.core.bz2 \ - test-core.exec.bz2 + test-core.exec.bz2 run-addr2line-test.sh
if USE_VALGRIND valgrind_cmd='valgrind -q --trace-children=yes --error-exitcode=1 --run-libc-freeres=no' diff --git a/tests/run-addr2line-test.sh b/tests/run-addr2line-test.sh new file mode 100755 index 0000000..768006b --- /dev/null +++ b/tests/run-addr2line-test.sh @@ -0,0 +1,74 @@ +#! /bin/sh +# Copyright (C) 2013 Red Hat, Inc. +# 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 http://www.gnu.org/licenses/. + +. $srcdir/test-subr.sh + +testfiles testfile +tempfiles good.out stdin.nl stdin.nl.out stdin.nonl stdin.nonl.out foo.out +tempfiles addr2line.out + +cat > good.out <<\EOF +foo +/home/drepper/gnu/new-bu/build/ttt/f.c:3 +bar +/home/drepper/gnu/new-bu/build/ttt/b.c:4 +foo +/home/drepper/gnu/new-bu/build/ttt/f.c:3 +bar +/home/drepper/gnu/new-bu/build/ttt/b.c:4 +foo +/home/drepper/gnu/new-bu/build/ttt/f.c:3 +bar +/home/drepper/gnu/new-bu/build/ttt/b.c:4 +foo +/home/drepper/gnu/new-bu/build/ttt/f.c:3 +bar +/home/drepper/gnu/new-bu/build/ttt/b.c:4 +EOF + +echo "# Everything on the command line" +cat good.out | testrun_compare ${abs_top_builddir}/src/addr2line -f -e testfile 0x08048468 0x0804845c foo bar foo+0x0 bar+0x0 foo-0x0 bar-0x0 + +cat > stdin.nl <<\EOF +0x08048468 +0x0804845c +foo +bar +foo+0x0 +bar+0x0 +foo-0x0 +bar-0x0 +EOF + +echo "# Everything from stdin (with newlines)." +cat stdin.nl | testrun ${abs_top_builddir}/src/addr2line -f -e testfile > stdin.nl.out || exit 1 +cmp good.out stdin.nl.out || exit 1 + +cat > foo.out <<\EOF +foo +/home/drepper/gnu/new-bu/build/ttt/f.c:3 +EOF + +echo "# stdin without newline address, just EOF." +echo -n "0x08048468" | testrun ${abs_top_builddir}/src/addr2line -f -e testfile > stdin.nonl.out || exit 1 +cmp foo.out stdin.nonl.out || exit 1 + +echo "# stdin without newline symbol, just EOF." +echo -n "foo" | testrun ${abs_top_builddir}/src/addr2line -f -e testfile > stdin.nl.out || exit 1 +cmp foo.out stdin.nonl.out || exit 1 + +exit 0
On Mon, 2013-08-12 at 14:49 +0200, Mark Wielaard wrote:
getline can return strings with a newline as last character when reading from stdin. This could cause confusing symbol lookup failures like: addr2line: cannot find symbol 'foo ' So if the last character of the buf returned by getline is a newline just null-terminate it right there. Also add a new testcase run-addr2line-test.sh.
I pushed this to master now.
Cheers,
Mark
elfutils-devel@lists.fedorahosted.org