From 7c6e785e6eca774080a64801f950bd61785c469e Mon Sep 17 00:00:00 2001 From: Jan Kratochvil Date: Wed, 15 Jan 2014 21:16:57 +0100 Subject: Fix corruption of non-C++ symbols by the demangler. Signed-off-by: Jan Kratochvil --- src/ChangeLog | 7 +++++ src/nm.c | 16 +++++----- src/stack.c | 5 +-- tests/ChangeLog | 14 +++++++++ tests/Makefile.am | 14 +++++++-- tests/run-backtrace-demangle.sh | 37 +++++++++++++++++++++++ tests/testfile-backtrace-demangle.bz2 | Bin 0 -> 2610 bytes tests/testfile-backtrace-demangle.cc | 47 +++++++++++++++++++++++++++++ tests/testfile-backtrace-demangle.core.bz2 | Bin 0 -> 40629 bytes 9 files changed, 127 insertions(+), 13 deletions(-) create mode 100755 tests/run-backtrace-demangle.sh create mode 100644 tests/testfile-backtrace-demangle.bz2 create mode 100644 tests/testfile-backtrace-demangle.cc create mode 100644 tests/testfile-backtrace-demangle.core.bz2 diff --git a/src/ChangeLog b/src/ChangeLog index d37cd1bb..50b6b588 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,10 @@ +2014-01-15 Jan Kratochvil + + Fix corruption of non-C++ symbols by the demangler. + * nm.c (show_symbols_sysv, show_symbols_bsd, show_symbols_posix) + (show_symbols): Check for _Z. + * stack.c (print_frames) : Check for _Z. + 2014-01-02 Mark Wielaard * stack.c (show_raw): Declare unconditionally. diff --git a/src/nm.c b/src/nm.c index d434f44e..62efb2d0 100644 --- a/src/nm.c +++ b/src/nm.c @@ -820,8 +820,8 @@ show_symbols_sysv (Ebl *ebl, GElf_Word strndx, const char *fullname, symstrbuf, sizeof symstrbuf); #ifdef USE_DEMANGLE - /* Demangle if necessary. */ - if (demangle) + /* Demangle if necessary. Require GNU v3 ABI by the "_Z" prefix. */ + if (demangle && symstr[0] == '_' && symstr[1] == 'Z') { int status = -1; char *dmsymstr = __cxa_demangle (symstr, demangle_buffer, @@ -965,8 +965,8 @@ show_symbols_bsd (Elf *elf, const GElf_Ehdr *ehdr, GElf_Word strndx, continue; #ifdef USE_DEMANGLE - /* Demangle if necessary. */ - if (demangle) + /* Demangle if necessary. Require GNU v3 ABI by the "_Z" prefix. */ + if (demangle && symstr[0] == '_' && symstr[1] == 'Z') { int status = -1; char *dmsymstr = __cxa_demangle (symstr, demangle_buffer, @@ -1076,8 +1076,8 @@ show_symbols_posix (Elf *elf, const GElf_Ehdr *ehdr, GElf_Word strndx, continue; #ifdef USE_DEMANGLE - /* Demangle if necessary. */ - if (demangle) + /* Demangle if necessary. Require GNU v3 ABI by the "_Z" prefix. */ + if (demangle && symstr[0] == '_' && symstr[1] == 'Z') { int status = -1; char *dmsymstr = __cxa_demangle (symstr, demangle_buffer, @@ -1244,8 +1244,8 @@ show_symbols (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, Elf_Scn *xndxscn, continue; #ifdef USE_DEMANGLE - /* Demangle if necessary. */ - if (demangle) + /* Demangle if necessary. Require GNU v3 ABI by the "_Z" prefix. */ + if (demangle && symstr[0] == '_' && symstr[1] == 'Z') { int status = -1; char *dmsymstr = __cxa_demangle (symstr, demangle_buffer, diff --git a/src/stack.c b/src/stack.c index fdf4b074..275be08c 100644 --- a/src/stack.c +++ b/src/stack.c @@ -1,5 +1,5 @@ /* Unwinding of frames like gstack/pstack. - Copyright (C) 2013 Red Hat, Inc. + Copyright (C) 2013-2014 Red Hat, Inc. This file is part of elfutils. This file is free software; you can redistribute it and/or modify @@ -220,7 +220,8 @@ print_frames (struct frames *frames, pid_t tid, int dwflerr, const char *what) if (symname != NULL) { #ifdef USE_DEMANGLE - if (! show_raw) + // Require GNU v3 ABI by the "_Z" prefix. + if (! show_raw && symname[0] == '_' && symname[1] == 'Z') { int status = -1; char *dsymname = __cxa_demangle (symname, demangle_buffer, diff --git a/tests/ChangeLog b/tests/ChangeLog index 7e9dcf4b..1b84f3a1 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,17 @@ +2014-01-15 Jan Kratochvil + + Fix corruption of non-C++ symbols by the demangler. + * Makefile.am (TESTS): Add run-backtrace-demangle.sh. + : Add ELFUTILS_DISABLE_DEMANGLE export. + (EXTRA_DIST): Add run-backtrace-demangle.sh, + testfile-backtrace-demangle.bz2, testfile-backtrace-demangle.cc, + testfile-backtrace-demangle.core.bz2. + * backtrace-demangle.cc: New file. + * run-backtrace-demangle.sh: New file. + * testfile-backtrace-demangle.bz2: New file. + * testfile-backtrace-demangle.cc: New file. + * testfile-backtrace-demangle.core.bz2: New file. + 2014-01-07 Matthias Klose * backtrace-subr.sh (check_native_core): Check to see if core file diff --git a/tests/Makefile.am b/tests/Makefile.am index eae64a83..1253574d 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,6 +1,6 @@ ## Process this file with automake to create Makefile.in ## -## Copyright (C) 1996-2013 Red Hat, Inc. +## Copyright (C) 1996-2014 Red Hat, Inc. ## This file is part of elfutils. ## ## This file is free software; you can redistribute it and/or modify @@ -107,12 +107,17 @@ TESTS = run-arextract.sh run-arsymtest.sh newfile test-nlist \ run-backtrace-native-biarch.sh run-backtrace-native-core.sh \ run-backtrace-native-core-biarch.sh run-backtrace-core-x86_64.sh \ run-backtrace-core-i386.sh run-backtrace-core-ppc.sh \ - run-backtrace-core-s390x.sh run-backtrace-core-s390.sh + run-backtrace-core-s390x.sh run-backtrace-core-s390.sh \ + run-backtrace-demangle.sh if !BIARCH export ELFUTILS_DISABLE_BIARCH = 1 endif +if !DEMANGLE +export ELFUTILS_DISABLE_DEMANGLE = 1 +endif + if !STANDALONE check_PROGRAMS += msg_tst md5-sha1-test TESTS += msg_tst md5-sha1-test @@ -256,7 +261,10 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \ run-backtrace-core-ppc.sh testfile66.bz2 testfile66.core.bz2 \ backtrace.s390x.core.bz2 backtrace.s390x.exec.bz2 \ backtrace.s390.core.bz2 backtrace.s390.exec.bz2 \ - run-backtrace-core-s390x.sh run-backtrace-core-s390.sh + run-backtrace-core-s390x.sh run-backtrace-core-s390.sh \ + run-backtrace-demangle.sh testfile-backtrace-demangle.bz2 \ + testfile-backtrace-demangle.cc \ + testfile-backtrace-demangle.core.bz2 if USE_VALGRIND valgrind_cmd='valgrind -q --error-exitcode=1 --run-libc-freeres=no' diff --git a/tests/run-backtrace-demangle.sh b/tests/run-backtrace-demangle.sh new file mode 100755 index 00000000..b5bddeb3 --- /dev/null +++ b/tests/run-backtrace-demangle.sh @@ -0,0 +1,37 @@ +#! /bin/bash +# Copyright (C) 2014 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 . + +if test -n "$ELFUTILS_DISABLE_DEMANGLE"; then + exit 77 +fi + +. $srcdir/backtrace-subr.sh +set -x + +child=testfile-backtrace-demangle +testfiles $child{,.core} +tempfiles $child.{bt,err} +testrun ${abs_top_builddir}/src/stack -e $child --core $child.core >$child.bt 2>$child.err +cat $child.{bt,err} +if ! grep -w f $child.bt; then + echo >&2 $2: no f + false +fi +if ! grep ' cxxfunc(int)' $child.bt; then + echo >&2 $2: no cxxfunc + false +fi diff --git a/tests/testfile-backtrace-demangle.bz2 b/tests/testfile-backtrace-demangle.bz2 new file mode 100644 index 00000000..c3156e89 Binary files /dev/null and b/tests/testfile-backtrace-demangle.bz2 differ diff --git a/tests/testfile-backtrace-demangle.cc b/tests/testfile-backtrace-demangle.cc new file mode 100644 index 00000000..6daa4297 --- /dev/null +++ b/tests/testfile-backtrace-demangle.cc @@ -0,0 +1,47 @@ +/* Test program for C++ demangled unwinding. + Copyright (C) 2014 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 . */ + +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) +#define NOINLINE_NOCLONE __attribute__ ((noinline, noclone)) +#else +#define NOINLINE_NOCLONE __attribute__ ((noinline)) +#endif + +static void NOINLINE_NOCLONE +cxxfunc (int i) +{ + *(volatile int *)0=0; + // Avoid tail call optimization. + asm volatile (""); +} + +extern "C" +{ + static void NOINLINE_NOCLONE + f (void) + { + cxxfunc(1); + // Avoid tail call optimization. + asm volatile (""); + } +} + +int +main() +{ + f(); +} diff --git a/tests/testfile-backtrace-demangle.core.bz2 b/tests/testfile-backtrace-demangle.core.bz2 new file mode 100644 index 00000000..c68edce1 Binary files /dev/null and b/tests/testfile-backtrace-demangle.core.bz2 differ -- cgit v1.2.1