diff options
author | Jan Kratochvil <jan.kratochvil@redhat.com> | 2012-11-20 16:14:23 +0100 |
---|---|---|
committer | Jan Kratochvil <jan.kratochvil@redhat.com> | 2012-11-20 16:14:23 +0100 |
commit | ae270c0db975005b86213167dc8539254dce41d9 (patch) | |
tree | 84c1a8967146d2775930a40201f4943f2f796e73 | |
parent | 3841068b5560f991c20e3c54b479ba4cc74c87ab (diff) | |
parent | 3d64327cf0d06cba090e9f734381ced18291c569 (diff) | |
download | elfutils-ae270c0db975005b86213167dc8539254dce41d9.tar.gz |
Merge branch 'jankratochvil/forunwind-baseaddr-hookvars-corereport-unwindx86-nonx86-fddebuginfo' into jankratochvil/forunwind-baseaddr-hookvars-corereport-unwindx86-nonx86-fddebuginfo-ports
-rw-r--r-- | backends/ppc64_init.c | 2 | ||||
-rw-r--r-- | libdwfl/dwfl_frame_unwind.c | 58 | ||||
-rwxr-xr-x | tests/run-backtrace.sh | 54 |
3 files changed, 45 insertions, 69 deletions
diff --git a/backends/ppc64_init.c b/backends/ppc64_init.c index 32ca876e..8b3c9462 100644 --- a/backends/ppc64_init.c +++ b/backends/ppc64_init.c @@ -71,8 +71,6 @@ ppc64_init (elf, machine, eh, ehlen) HOOK (eh, frame_state); HOOK (eh, abi_cfi); HOOK (eh, frame_dwarf_to_regno); - HOOK (eh, get_func_pc); - HOOK (eh, destr); return MODVERSION; } diff --git a/libdwfl/dwfl_frame_unwind.c b/libdwfl/dwfl_frame_unwind.c index e35ccb5d..c1a81b15 100644 --- a/libdwfl/dwfl_frame_unwind.c +++ b/libdwfl/dwfl_frame_unwind.c @@ -312,46 +312,6 @@ have_unwound (Dwfl_Frame_State **statep) abort (); } -/* Check if PC is in the "_start" function which may have no FDE. - It corresponds to the GDB get_prev_frame logic "inside entry func". - Return TRUE if PC is in an outer frame. Return FALSE (and call - __libdwfl_seterrno) otherwise. */ - -static bool -no_fde (Dwarf_Addr pc, Dwfl_Module *mod, Dwarf_Addr bias) -{ - GElf_Sym sym; - const char *symname = INTUSE(dwfl_module_addrsym) (mod, pc, &sym, NULL); - if (symname == NULL) - { - __libdwfl_seterrno (DWFL_E_NO_DWARF); - return false; - } - /* It has no FDE on PPC64; it can be still unwound via the stack frame. */ - if (strcmp (symname, ".generic_start_main") == 0) - return true; - GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (mod->main.elf, &ehdr_mem); - if (ehdr == NULL) - { - __libdwfl_seterrno (DWFL_E_LIBELF); - return false; - } - if (pc < ehdr->e_entry + bias) - { - __libdwfl_seterrno (DWFL_E_NO_DWARF); - return false; - } - /* "_start" is size-less. Search for PC, if the closest symbol is the one - for E_ENTRY it belongs into the function starting at E_ENTRY. */ - if (sym.st_value != ehdr->e_entry + bias - || (sym.st_size != 0 && pc >= sym.st_value + sym.st_size)) - { - __libdwfl_seterrno (DWFL_E_NO_DWARF); - return false; - } - return true; -} - /* The logic is to call __libdwfl_seterrno for any CFI bytecode interpretation error so one can easily catch the problem with a debugger. Still there are archs with invalid CFI for some registers where the registers are never used @@ -362,22 +322,12 @@ no_fde (Dwarf_Addr pc, Dwfl_Module *mod, Dwarf_Addr bias) an undefined PC register (due to an error unwinding it). */ static bool -handle_cfi (Dwfl_Frame_State **statep, Dwarf_Addr pc, Dwfl_Module *mod, - Dwarf_CFI *cfi, Dwarf_Addr bias) +handle_cfi (Dwfl_Frame_State **statep, Dwarf_Addr pc, Dwarf_CFI *cfi) { Dwfl_Frame_State *state = *statep; Dwarf_Frame *frame; - if (INTUSE(dwarf_cfi_addrframe) (cfi, pc - bias, &frame) != 0) + if (INTUSE(dwarf_cfi_addrframe) (cfi, pc, &frame) != 0) { - int dw_errno = dwarf_errno (); - if (dw_errno == DWARF_E_NO_MATCH) - { - if (! no_fde (pc, mod, bias)) - return false; - *statep = NULL; - return true; - } - __libdw_seterrno (dw_errno); __libdwfl_seterrno (DWFL_E_LIBDW); return false; } @@ -474,7 +424,7 @@ dwfl_frame_unwind (Dwfl_Frame_State **statep) Dwarf_CFI *cfi_eh = INTUSE(dwfl_module_eh_cfi) (mod, &bias); if (cfi_eh) { - if (handle_cfi (statep, pc, mod, cfi_eh, bias)) + if (handle_cfi (statep, pc - bias, cfi_eh)) return true; if (state->unwound) { @@ -485,7 +435,7 @@ dwfl_frame_unwind (Dwfl_Frame_State **statep) Dwarf_CFI *cfi_dwarf = INTUSE(dwfl_module_dwarf_cfi) (mod, &bias); if (cfi_dwarf) { - if (handle_cfi (statep, pc, mod, cfi_dwarf, bias) && state->unwound) + if (handle_cfi (statep, pc - bias, cfi_dwarf) && state->unwound) return true; if (state->unwound) { diff --git a/tests/run-backtrace.sh b/tests/run-backtrace.sh index a57d4744..0d1e7370 100755 --- a/tests/run-backtrace.sh +++ b/tests/run-backtrace.sh @@ -27,41 +27,69 @@ mytestrun() testrun "$@" } +check_main() +{ + if grep -w main $1; then + return + fi + cat >&2 $1 + echo >&2 $2: no main + false +} + check_gsignal() { # Without proper ELF symbols resolution we could get inappropriate weak # symbol "gsignal" with the same address as the correct symbol "raise". - if grep -w gsignal $1; then - false + if ! grep -w gsignal $1; then + return fi + cat >&2 $1 + echo >&2 $2: found gsignal + false } -check_empty() +check_err() { - if test -s $1; then - false + if test ! -s $1; then + return + fi + # In some cases we cannot reliably find out we got behind _start. + if echo "No DWARF information found" | cmp -s - $1; then + return fi + cat >&2 $1 + echo >&2 $2: neither empty nor just out of DWARF } for child in backtrace-child{,-biarch}; do - mytestrun ./backtrace ./$child + tempfiles $child{.bt,err} + ./backtrace ./$child 1>$child.bt 2>$child.err \ + || true + check_main $child.bt $child + check_gsignal $child.bt $child + check_err $child.err $child core="core.`ulimit -c unlimited; set +e; ./$child --gencore --run; true`" tempfiles $core{,.bt,.err} - mytestrun ./backtrace ./$child ./$core 1>$core.bt 2>$core.err + ./backtrace ./$child ./$core 1>$core.bt 2>$core.err \ + || true cat $core.{bt,err} - check_gsignal $core.bt - check_empty $core.err + check_main $core.bt $child-$core + check_gsignal $core.bt $child-$core + check_err $core.err $child-$core done for arch in ppc ppc64 s390 s390x; do testfiles backtrace.$arch.{exec,core} tempfiles backtrace.$arch.{bt,err} echo ./backtrace ./backtrace.$arch.{exec,core} - mytestrun ./backtrace ./backtrace.$arch.{exec,core} 1>backtrace.$arch.bt \ - 2>backtrace.$arch.err + ./backtrace ./backtrace.$arch.{exec,core} 1>backtrace.$arch.bt \ + 2>backtrace.$arch.err \ + || true cat backtrace.$arch.{bt,err} - check_gsignal backtrace.$arch.bt - check_empty backtrace.$arch.err + check_main backtrace.$arch.bt $arch + check_gsignal backtrace.$arch.bt $arch + check_err backtrace.$arch.err $arch done exit 0 |