1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2024-11-23 07:57:38 +01:00
Commit graph

3047 commits

Author SHA1 Message Date
Christopher Ferris
cf6382643e Add aarch64 getcontext functionality.
Change-Id: I32912a85c0fd02bb5e45a9eb7deb2410ded352a9
2017-01-24 11:08:28 -08:00
Frederik Carlier
d9797d9562 Add Travis CI support 2017-01-24 11:07:48 -08:00
Frederik Carlier
1ec8d115ff Update .gitignore 2017-01-24 11:07:41 -08:00
Saleem Abdulrasool
e9e8ed73e3 dwarf: Account for multiple CFA for args_size
It is possible to have multiple CFA_args_size adjustments for a single
frame.  If the CFA_args_size adjustment is immediately following the
return from a function which can raise an exception, it is possible to
incorrectly adjust the stack pointer.  Consider the following:

  ...
  .cfi_escape 0x2e, 0x00
  call f
.Ltmp:
  .cfi_escape 0x2e, 0x10
  lea label@GOTOFF(%ebx), %eax
  ...

Because we process the CFI program up to and *INCLUDING* IP, where the
IP is the RA, we would process the associated DW_CFA_GNU_args_size for
the post-call instruction.  The result would be a DW_CFA_GNU_args_size
of 0x10 rather than 0x00, resulting in an incorrect stack adjustment.
Handle this by processing the CFI operation but not adjusting the state
record unless we are below the current IP.
2017-01-19 10:07:53 -08:00
Konstantin Belousov
9e97c9b17a dwarf: Make binary path calculation os-specific.
/proc/self/exe only works on Linux, move path computation to os-* files
2017-01-19 10:07:13 -08:00
Vitaly Kuzmichev
7885596b9c arm: ptrace: Fix order of probing unwind tables
Commit 92327a3 "ARM: prefer to unwind using DWARF info"
changes order of unwind info searching to prefer DWARF (.debug_frame)
section in prior to ARM specific (.ARM.exidx). This patch only affects
local process unwinding. Now the same is done for remote unwinding.

Sometimes probing .ARM.exidx first causes backtrace truncation
after __aeabi_ldiv0 (division by 0 handler that generates SIGFPE),
because it hits [cantunwind] generated by cross-gcc for __divsi3
function copied with __aeabi_ldiv0 from libgcc.a. Perhaps, lack of
debug info for __divsi3 causes [cantunwind], or there is a problem
converting DWARF to ARM unwind tables, but when unwinding using
DWARF, it hits proper entry, and backtrace is shown correctly.

Reported-by: Frederic Berat <fberat@de.adit-jv.com>
Signed-off-by: Vitaly Kuzmichev <Vitaly_Kuzmichev@mentor.com>
2017-01-19 10:06:24 -08:00
Saleem Abdulrasool
11a053f5ca use target dependent names for stack registers
When adjusting the stack for a DW_CFA_arg_size adjustment, ensure that
we use the target dependent register name as the generic name does not
necessarily map to the same register.  For example, on x86, ESP maps to
the eip register, which results in the wrong stack adjustment being
applied.
2017-01-18 10:17:15 -08:00
Konstantin Belousov
09a598a3da Make the code compile on FreeBSD. 2017-01-18 09:18:29 -08:00
Guy Menanteau
7c079200d0 ppc64: Make access_fpreg function accept fp and v registers 2017-01-13 08:41:45 -08:00
Martin Dorey
1f4929c05d linux: Add /usr/lib/debug symbol path checking
Debian likes to hive off symbol information to separate -dbg packages,
installing the debug information in a parallel tree rooted at /usr/lib/debug.
libunwind doesn't know how to find these files but it's easy, per the tested,
attached patch, to make it so. I don't see /usr/lib/debug at
http://www.pathname.com/fhs/pub/fhs-2.3.html#USRLIBLIBRARIESFORPROGRAMMINGANDPA
but
https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/4/html/Debugging_with_gdb/separate-debug-files.html
says it's not just Debian and hints it might be driven by gdb. I do see mention
of /usr/lib/debug in libunwind already, but only in a DWARF-specific part of
the code.  A minor concern might be checking errno to see if the problem is
ENOENT before trying the alternate path. That might be better than flogging a
mmap problem or being out of file handles or whatever.
2017-01-13 08:36:37 -08:00
Dave Watson
a51cf49031 dwarf: Configurable cache size
Add interface for configurable dwarf cache size

* Use item size and round up to nearest power of 2.
* Initial cache still exists in BSS.  Without this, it means we would fail
  backtrace when out of memory.  The test-mem test fails without this
2017-01-13 08:36:33 -08:00
Dave Watson
29483327be x86_64: Use sigprocmask from signal frames
Currently setcontext for x86_64 restores the signal mask, even
though it is never saved anywhere.  This means the signal mask
is often garbage after an unw_resume.

(changed in commit f8a15e9679)

It looks like this was a fix for the Gtest-resume-sig function -
testing if signal masks are restored across signal frames.  The
root issue looks like that x86_64 only uses sigreturn for the exact
signal frame, and not for any decedant frames as well (as i64 does).

Instead, modify Gresume to use sigreturn if *any* frame on the stack
is a signal frame, so that we correct fixup the signal mask and any
sigaltstacks.  The sigreturn os-specific functions are changed slightly
to copy in the saved ucontext structure if we are jumping farther
up the stack.

This should fix sigprocmask reported issues such as
https://github.com/dropbox/pyston/blob/master/libunwind_patches/0002-pyston-stop-x86_64-setcontext-restoring-uninitialize.patch

Tests pass on freebsd, linux
2017-01-13 08:28:22 -08:00
Petr Malat
b707e13ca0 tests: Use strtoul in test-coredump-unwind.c
Read the address using strtoul(). If strtol() is used and the number is
bigger than LONG_MAX, LONG_MAX is returned instead, which leads to a failure
if the mapping address is 0x80000000 or larger on 32-bit platforms (and
similarly for 64-bit platforms).
2017-01-13 08:28:21 -08:00
Dave Watson
4b63a536ee dwarf: Correct handling of DW_CFA_GNU_args_size
When resuming execution, DW_CFA_GNU_args_size from the current frame
must be added back to the stack pointer.  Clang now generates these frequently
at -O3.  A simple repro for x86_64, that will crash with clang ~3.9 or newer:

void f(int, int,int,int,int,int,int,int,int);

int main() {
  try {
    f(0,1,2,3,4,5,6,7,8);
  } catch (int) {
    return 0;
  }
  return 1;
}

Where f is something that throws an int, but in a different translation unit to
prevent optimization.

This results in cfi instructions before the call:
 .cfi_escape 0x2e, 0x20

Grabbing the args_size means fully parsing the cfi in the current frame, which
is unfortunate because it means nearly twice the work at each step.  The logic
to grab args_size can be in unw_step or get_proc_info (since this is always
called before resuming in stack unwinding).  Putting it in get_proc_info allows
the more common unw_step code to remain fast.

It would potentially fit in nicely with a proc info cache (as mentioned in the
if0 comment block)
2017-01-13 08:28:21 -08:00
Dave Watson
f7fe1c9a7e x86_64: Add stack alignment prologue tdep_trace fastpath
GCC versions 4.9~current will often generate stack alignment prologues like:

lea 0x8(%rsp),%r10
and $0xfffffffffffffff0,%rsp
...
push %rbp
mov %rsp, %rbp
push %r10

resulting in dwarf expressions:
DW_CFA_def_cfa_expression (DW_OP_breg6: -8; DW_OP_deref)
DW_CFA_expression: r6 (rbp) (DW_OP_breg6: 0)

These prologues seem to be generated for SSE/AVX code, but sometimes
other times as well.

tdep_trace fastpath currently falls back to the slow dwarf parsing path
if it encounters any cfa_expressions. Unfortunately this is happening
often enough in our codebase to cause perf issues.  We could also fix the
fallback path (make the rs cache bigger, lock-free instead of locking, etc),
but that seems like a separate issue, and it will ever be as fast as the tracing
code.   Our binaries each have at least ~100 functions in them like this.

This patch teaches the tdep_trace about the two specific cfa_expressions,
which really just result in a single extra memory dereference of the stack
at a fixed offset from rbp.
2017-01-13 08:28:21 -08:00
Jan Willeke
e5fe9034ad coredump: align coredump description pointer
next = inote.descdata + align_power (inote.descsz, 2);

this align is missing, leading to parsing errors. In one case
libunwind only found 1 thread out of 4.
2017-01-13 08:28:21 -08:00
Jonathan Byrd
25413c729a dwarf: Improve support for binaries missing the GNU_EH_FRAME segment
Improves support for binaries missing the GNU_EH_FRAME segment
(.eh_frame_hdr section) by adding a function
'dwarf_find_eh_frame_section' that can create a synthetic one.
2017-01-13 08:28:21 -08:00
Dave Watson
32e3e93b01 tests: Walk default test arguments to ensure child process has visibility 2017-01-13 08:28:21 -08:00
Tony Kelman
5dcb7cd3cb Fix compilation of tests on alpine linux (musl libc)
If we don't link to libexecinfo, as detected by the
AC_SEARCH_LIBS(backtrace, execinfo) configure probe, we get

```
test-coredump-unwind.o: In function `handle_sigsegv':
/home/libunwind/tests/test-coredump-unwind.c:246: undefined reference to
`backtrace_symbols_fd'
collect2: error: ld returned 1 exit status
Makefile:1187: recipe for target 'test-coredump-unwind' failed
```

and

```
Gtest-init.o: In function `do_backtrace()':
Gtest-init.cxx:(.text+0x2f): undefined reference to `_Ux86_64_getcontext'
Gtest-init.cxx:(.text+0x48): undefined reference to `_Ux86_64_init_local'
Gtest-init.cxx:(.text+0x63): undefined reference to `_Ux86_64_get_reg'
Gtest-init.cxx:(.text+0x96): undefined reference to `_Ux86_64_get_proc_name'
Gtest-init.cxx:(.text+0x171): undefined reference to `_Ux86_64_step'
collect2: error: ld returned 1 exit status
Makefile:1063: recipe for target 'Gtest-init' failed
```

There are 2 XFAIL and 6 FAIL tests, but it's a start
2017-01-13 08:28:21 -08:00
Королев Сергей
fd44f596b2 tdep_uc_addr: use +4 offset for UNW_MIPS_PC on MIPS (be)
According to mcontext_t definition its "pc" field
is also 64 bit wide and thus requires 4 byte offset
on MIPS32 (be).
2017-01-13 08:27:40 -08:00
Chris Redmon
cf2bc87561 Fixup invalid return code checks of unw_is_signal_frame()
unw_is_signal_frame() returns <= 0 if not a signal frame. Several places in
code were only checking for a "if (unw_is_signal_frame())", or
"if (!unw_is_signal_frame())".
2017-01-13 08:27:40 -08:00
Mike Frysinger
67d4137ba7 tests: simplify make variables a bit
Add dummy assign statements at the top so we don't have to trace all
the different if paths to see where the value is initially assigned.
Now all code paths just append it.
2017-01-13 08:27:40 -08:00
Королев Сергей
208a430bcb add --disable-tests option
Allows to skip tests build.
2017-01-13 08:27:39 -08:00
Королев Сергей
ad0d7633bc dwarf: check maps_init result
This fixes GCC 4.9.3 warnings (Linux/mipsel):

dwarf/Gfind_proc_info-lsb.c: In function 'locate_debug_info':
dwarf/Gfind_proc_info-lsb.c:244:23: warning: 'mi.buf_end' may be used
uninitialized in this function [-Wmaybe-uninitialized]
   struct map_iterator mi;
                       ^
dwarf/Gfind_proc_info-lsb.c:244:23: warning: 'mi.buf' may be used
uninitialized in this function [-Wmaybe-uninitialized]
In file included from dwarf/Gfind_proc_info-lsb.c:46:0:
./os-linux.h:292:27: warning: 'mi.buf_size' may be used uninitialized in
this function [-Wmaybe-uninitialized]
       munmap (mi->buf_end - mi->buf_size, mi->buf_size);
                           ^
dwarf/Gfind_proc_info-lsb.c:244:23: note: 'mi.buf_size' was declared here
   struct map_iterator mi;
                       ^
2017-01-13 08:27:39 -08:00
Dave Watson
0326f1048a Bump version to 1.2 2017-01-13 08:07:51 -08:00
Dave Watson
7d30e028a2 Don't build dyn tests on non-ia64
It looks like the dynamic frame support isn't fully baked on
non-ia64, leading to lots of mailing list comments about broken
tests (even though they're marked as supposed to fail, it's still
confusing).
2017-01-06 15:43:35 -08:00
Giuseppe Ottaviano
bc8698fd7e [PATCH] x86_64: fix mincore_validate
The detection logic introduced in 28f33c8ce0 is
broken, because it tests mincore using an address that is almost certainly not
page-aligned. straces confirms that msync is used all the time.

This patch fixes the logic by page-aligning the test pointer. strace now shows
that mincore is actually used. Furthermore, the return value of mincore is not
sufficient to assess whether the address can be safely dereferenced: we should
also check that the pages are mapped, through the passed mvec array. This patch
also adds this verification.

Tested on a system where unwinding a stack across a JNI boundary would cause
sporadic segfaults; no more crashes were observed after the patch.
2016-02-29 11:05:42 -08:00
Ulrich Weigand
c56fb8f99e ppc64: Fix serious regression (many crashes in test suite)
A recent commit added code to override the unwind location for the
TOC pointer register r2:

    unsigned int *inst = (unw_word_t*)c->dwarf.ip;
    if (*inst == (0xE8410000 + 24)) {
      // @plt call, restoring R2 from CFA+24
      c->dwarf.loc[UNW_PPC64_R2] = DWARF_LOC(c->dwarf.cfa + 24, 0);
    }

It is correct that such code is needed, since DWARF CFI does not
describe the unwind location for r2 on PowerPC.  However, this
particular bit of code has a number of issues, which are fixed
in this patch.

First of all, the location CFA+24 is correct only for the ELFv2
ABI.  In the ELFv1 ABI, the TOC location is actually CFA+40.

More problematically, attempting to read the current instruction
by just dereferencing the address in c->dwarf.ip is wrong, and
may often lead to crashes.  In particular:

- During remote unwinding, this is always wrong since we're in
  the wrong address space.  I've used the fetch32 helper from
  remote.h to use the proper access_mem under the covers.

- c->dwarf.ip may be NULL if we've reached the end-of-stack.
  I've fixed this by moving the c->dwarf.ip == 0 check down
  to after unwinding (instead of before), just like all other
  platforms do.

- Even so, c->dwarf.ip may point to some random location if
  we've gotten confused during unwinding earlier.  One likely
  cause for such confusion is that we did not find DWARF CFI
  for some earlier frame and attempted to use the stack
  backchain.  The problem is that this code currently claims
  all registers remain unchanges in such a frame, which is
  generally wrong.  In particular if the function actually
  saves and modifies r31, and this is used as frame pointer
  by a later frame, things will likely go quite wrong.  While
  it is not really possibly to completely fix this, I've at
  least marked all registers as unavailable after unwinding
  a frame via stack backchain.

Tested on powerpc64-linux and powerpc64le-linux.  The patch fixes
about a dozen test cases that were crashing before.

Signed-off-by: Ulrich Weigand <ulrich.weigand@de.ibm.com>
2015-12-06 11:10:10 -08:00
Keno Fischer
8afc33ce9f Add an option to have start_ip_offset be relative to start_ip
By default, the start_ip_offset in libunwind's table_entry struct is
relative to the unw_dyn_info_t's segbase. This presents a problem
for us in conjunction with using LLVM's MCJIT because it likes to
spread text sections and the corresponding eh_frame sections quite
far apart. This represents my attempt to support this use case in the
simplest manner that is backwards compatible, by adding a new format
kind (UNW_INFO_FORMAT_REMOTE_TABLE2) that indicates that the
`start_ip_offset` should be interpreted as relative to `start_ip`
rather than segbase.
2015-09-15 12:18:30 -07:00
Alexander Esilevich
d1a8ca6d84 powerpc64 implementation 2015-09-07 18:08:26 -07:00
Arun Sharma
923fa78e79 Revert parts of 68a2910
The check breaks a few tests when used with gold.
2015-09-07 17:59:27 -07:00
Arun Sharma
396b6c7ab7 Invalid dwarf opcodes can cause references beyond the end of the array. 2015-06-19 19:47:22 -07:00
Milian Wolff
b2db825e8a Update README to use autogen.sh 2015-06-07 12:23:42 -07:00
Vyacheslav Barinov
7701522688 arm: Validate memory before access
Prevent SIGSEGV due to accessing addresses now mapped to current process

Signed-off-by: Vyacheslav Barinov <v.barinov@samsung.com>
2015-06-07 12:17:40 -07:00
Faraz Shahbazker
16bf4e5e49 Stack-unwinding through signal frames on mips
Detect if current frame is a signal frame by checking for preceeding
syscall instruction. For signal frames, update the cursor correctly
from user context before calling dwarf_step.
2015-04-02 11:20:33 -07:00
Andreas Schwab
544cdb3b43 tests/Gtest-trace.c: show differing addresses 2015-03-22 00:05:14 -07:00
Gregory Fong
0bed10aa21 Mark run-ptrace-mapper and run-ptrace-misc as XFAIL on ARM
This is similar to commit c90a2e02b3
"Mark run-ptrace-mapper and run-ptrace-misc as XFAIL on MIPS".
Starting with 2.6.39, ARM Linux returns -EIO for PTRACE_SINGLESTEP, so
we need to mark this as XFAIL for ARM too.

The Linux commit that changed this is

   commit 425fc47adb5bb69f76285be77a09a3341a30799e
   Author: Will Deacon <will.deacon@arm.com>
   Date:   Mon Feb 14 14:31:09 2011 +0100

       ARM: 6668/1: ptrace: remove single-step emulation code

see: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=425fc47adb5bb69f76285be77a09a3341a30799e

Signed-off-by: Gregory Fong <gregory.0xf0@gmail.com>
2015-02-21 13:00:34 -08:00
Peter Wu
68a2910bae Check that the CIE is within the segment
Due to a bug in the gold linker[1], the .eh_frame and .eh_frame_hdr
sections contains garbage. When dwarf_extract_proc_info_from_fde tried
to look up the begin of the CIE subsection, it would underflow the
.eh_frame segment, resulting in a crash[2].

This patch avoids that crash by checking whether the CIE pointer is
located after the begin of the .eh_frame section. The variable "base"
was misused in various places as a boolean (decode as .debug_frame or
decode as .eh_frame). These instances have been renamed to
is_debug_frame where applicable.

Tested on Linux x86_64.

 [1]: https://sourceware.org/bugzilla/show_bug.cgi?id=17639
 [2]: http://lists.nongnu.org/archive/html/libunwind-devel/2014-11/msg00009.html

Signed-off-by: Peter Wu <peter@lekensteyn.nl>
2014-12-05 23:39:48 -08:00
Olivier Fourdan
6e3254ea6e [PATCH] Fix build from scratch
- Add autogen.sh to bootstrap autotools generation
- Make generation of man pages optional, and check for
  availibity of latex2man if documentation is requested.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Signed-off-by: Arun Sharma <asharma@fb.com>
2014-12-04 00:12:00 -08:00
Victor Kamensky
16e98c8cf3 aarch64: fix wrong big_endian flag in aarch64_be case
Set local_addr_space.big_endian flag according to current target
endianness. Before it was set by memset to 0, which corresponds
to little endian and it worked perfectly fine for aarch64.
But it breaks aarch64_be because dwarf_readu16, dwarf_readu32,
etc functions do not read values correctly since they operate
with wrong idea about current target endianness.

Signed-off-by: Victor Kamensky <victor.kamensky@linaro.org>
2014-12-03 23:28:07 -08:00
Victor Kamensky
743668f669 aarch64: introduce build support for aarch64_be target
Introduce support for aarch64_be, aarch64 big endian, target.
We would like to reuse all code that was done for aarch64
(little endian) target. So we do similar thing that is done
for ARM v7 (arm) target for any aarch64* arch we set it
just to aarch64.

Signed-off-by: Victor Kamensky <victor.kamensky@linaro.org>
2014-12-03 23:26:27 -08:00
C. Bergström
3babc1d148 aarch64: Restore x0, x1, x2 and x3
These registers contain the exception pointer and selector.
2014-10-24 22:40:19 -07:00
Simon Atanasyan
c90a2e02b3 Mark run-ptrace-mapper and run-ptrace-misc as XFAIL on MIPS
Though PTRACE_SINGLESTEP is defined on MIPS Linux, the kernel does
not support that kind of request. The ptrace call failed and sets
errno to EIO and paused process is not resumed. In case of
run-ptrace-mapper and run-ptrace-misc this leads to hanged execution
because next call to wait4 never returns.

This change adds run-ptrace-mapper and run-ptrace-misc to the list
of 'expected failed' tests on MIPS targets.

Signed-off-by: Simon Atanasyan <simon@atanasyan.com>
2014-10-24 22:31:05 -07:00
Paul Pluzhnikov
1bca6eb8ea Remove unnecessary calls to labs()
We've just traced a large memory increase to that patch (Google ref:
b/18069427).
It appears that labs() was there for a good reason.

Sorry about that :-(

For the curious:

  unsigned long u1 = ~0UL;
  unsigned long u2 = labs(u1);

  assert(u1 != u2);  // labs on unsigned *may* have an effect, despite
what Clang says.

Attached patch suppresses the Clang warning, while still keeping the
original behavior (which I believe to be correct).

Thanks,
--
Paul Pluzhnikov
2014-10-24 22:29:15 -07:00
Simon Atanasyan
5b37b3cff1 Fix intermittent failures of Lrs-race test case
After the following change the Lrs-race test case starts to intermittently
fails:

eac65dc Add basic support for the QNX operating system

When we include "config.h" into the "libunwind_i.h" we undefine
the HAVE___THREAD macro in a few lines below in #include "config.h"
pragma. The change eac65dc includes "config.h" into the "dwarf.h"
but forgets to undefine HAVE___THREAD. So now this macro has inconsistent
state among the code. Somewhere it is defined, somewhere not. In particular
it becomes defined in the mi/Gset_caching_policy.c and we do not replace
UNW_CACHE_PER_THREAD caching policy by the UNW_CACHE_GLOBAL.

The fix is rather dirty. It adds the code to undefine HAVE___THREAD in
the "dwarf.h" like we do that in the "libunwind_i.h". Probably the ideal
solution should fix per-thread caching implementation or turned it off
at all on platforms where it is not completely and correctly supported.

Signed-off-by: Simon Atanasyan <simon@atanasyan.com>
2014-10-24 22:05:46 -07:00
Arun Sharma
44b867c650 Store location type in local unwinding mode for x86_64
Helps support DW_CFA_val_expression
2014-10-04 09:04:08 -07:00
Arun Sharma
781d5d5263 One time whitespace fixup.
for f in $(find src include -name '*.[ch]'); do
  expand -t 8 $f > $tmp; mv $tmp $f;
done
2014-09-27 09:47:23 -07:00
Arun Sharma
06e608d043 Merge branch 'fast-stack-trace-arm' of https://github.com/fillexen/libunwind 2014-09-20 08:09:55 -07:00
Arun Sharma
6046c87d8e Merge branch 'fast-stack-trace-aarch64' of https://github.com/fillexen/libunwind 2014-09-20 08:09:35 -07:00
Arun Sharma
5d79a12ec0 Merge https://github.com/zliu2014/libunwind-tilegx 2014-09-20 00:47:23 -07:00