1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2024-11-19 06:17:37 +01:00
Commit graph

158 commits

Author SHA1 Message Date
Johannes Ziegenbalg
836c91c43d x86_64: fix mincore_validate and msync_validate
The calls to mincore() or msync() are not checking for actual accessibility
this could lead to SIGSEGV if the address from a mapped page with the
PROT_NONE property occurs on the stack.
Hence an attempt to write one byte from the checked address to a pipe will
fail if the address is not readable.
2017-08-24 08:50:07 -07:00
Yichao Yu
e9e50d07b0 x86_64: Use ucontext_t instead of struct ucontext
Ref https://sourceware.org/git/?p=glibc.git;a=commit;h=251287734e89a52da3db682a8241eb6bccc050c9
And this is what other part of the code uses.
2017-08-22 11:51:20 -07:00
Felipe Cerqueira
819bf51bbd dwarf: Fix uninitialized variable c->dwarf.eh_valid_mask.
We were testing libunwind-coredump and got some warnings about
uninitialized eh_valid_mask.
The code was working fine because the default value of the mask was 0, but
it could potentially take a wrong branch if there's garbage in memory.
2017-08-17 14:18:07 -07:00
Dave Watson
644cce3d72 half finished unw_local_init2 2017-08-16 11:27:43 -07:00
Bert Wesarg
57257060c9 Bring back support for UNW_CACHE_PER_THREAD.
Needs to be build with --enable-per-thread-cache. Default caching policy
is also UNW_CACHE_PER_THREAD than.
2017-08-15 10:34:28 -07:00
Doug Moore
27f5f9fa0b Leave ret_addr_column out of the data that gets copied when pushing/popping
data on/off the register state stack.
2017-05-20 14:36:25 -05:00
Doug Moore
c66661f73c Drop reference to dwarf.ret_addr_column. 2017-05-19 19:19:12 -05:00
Doug Moore
afb2491ccb Have dwarf_step return 0 or 1 for success, according to whether the
previous stack frame was the last, just as unw_step does.  For x86_64,
drop the null check for ret_addr_column, since that check is made already
in apply_reg_state.
2017-05-19 18:57:14 -05:00
Doug Moore
f3be411bc8 Use the register_state version of ret_addr_column, rather than the
cursor version, for frame-stashing.  They have the same value in master.
2017-05-19 18:22:08 -05:00
Doug Moore
028a60f064 Change dwarf_reg_state from an array of pairs of differently-sized objects
to a pair of arrays, to reduce internal fragmentation.  Reduces storage
use by 37.5% on x86_64.
2017-05-16 17:40:58 -05:00
Doug Moore
fef5de6c45 Move ret_addr_column and signal_frame from dwarf_reg_state to
dwarf_reg_cache_entry, leaving in dwarf_reg_state only what
apply_reg_state needs.
2017-05-12 22:24:00 -05:00
Doug Moore
502ba27753 Add a function to capture the dwarf_reg_states that occur in processing
the dwarf code for a procedure, and a function to apply a captured
dwarf_reg_state later.
2017-05-12 22:24:00 -05:00
Doug Moore
14c48b3d51 unw_init_local_signal
init_local, but *not* setting use_prev_instr.
This is necessary to correctly unwind using ucontext argument to signal handlers.
2017-04-03 14:44:40 -07:00
Bert Wesarg
4dea379ad9 x84_64: It's only 'mcontext_t'.
Fixes warning:
```
src/x86_64/Gos-linux.c:141:36: warning: initialization from incompatible pointer type
   struct mcontext_t *sc_mcontext = &((struct ucontext*)sc)->uc_mcontext;
                                    ^
```

Introduced-in: 29483327be
2017-01-24 11:09:14 -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
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
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
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
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
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
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
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
0808aa6737 Stop unwinding on undefined return address
Milian Wolff <mail@milianw.de> reported that this greatly
improved unwinding perf on some his apps.
2014-09-07 03:32:57 -07:00
Paul Pluzhnikov
e63cadf76d Remove unnecessary calls to labs()
Greetings,

Roman reports that Clang warns on unnecessary calls to labs():

  taking the absolute value of unsigned type 'unw_word_t' (aka
'unsigned long') has no effect [-Werror,-Wabsolute-value]

Since rs->reg[...].val is unw_word_t and unsigned on all platforms,
this patch removes the unnecessary calls to labs().

Tested on Linux x86_64, no regressions.

Thanks,
--
Paul Pluzhnikov
2014-08-15 13:01:47 -07:00
Konstantin Belousov
3723511003 Adjust use_prev_instr for syscall and frame-chain frames.
Mark frames which are unwound with the frame-chain walker or
syscall frame code, as non-interrupted.  The return PC in the frame
points to the instruction after the call.
2014-08-15 13:01:36 -07:00
Kevin Modzelewski
4509adb853 x86_64: Handle edge conditions with zero length frames
When JITs generate code without unwind information, it may be possible
to continue unwinding via RBP chaining. However, we currently disallow
RBP==RSP condition even though we can make forward progress.

Relax the check a bit in the code where we switch from one type of
unwinding to another to handle this situation. JIT authors
are encouraged to use the dynamic unwind info registration API when
the underlying platform supports it.

Signed-off-by: Kevin Modzelewski <kmod@dropbox.com>
2014-05-18 19:39:26 -07:00
Tommi Rantala
adae66d2e2 Fix x86-64 debug build -Wformat warning
src/x86_64/Gstep.c: In function '_ULx86_64_step':
src/x86_64/Gstep.c:204:4: warning: unknown conversion type character 'r' in format [-Wformat]
2012-10-05 21:24:36 -07:00
Tommi Rantala
890e23eb9d Prefer NULL over zero 2012-09-28 14:51:21 +03:00
Tommi Rantala
aebba1f8a7 Apply `define_lock()'
We have a nice macro for defining pthread mutexes, use it.
2012-09-28 14:51:21 +03:00
Tommi Rantala
ee8df26288 Constify `dwarf_to_unw_regnum_map' 2012-09-28 14:50:03 +03:00
Tommi Rantala
ded94b98ff Stop including `memory.h'
I am unable to find any reference to `memory.h' in the C99 and C11
committee drafts, so include `string.h' instead when we need memset() or
similar.
2012-09-28 14:50:03 +03:00
Tommi Rantala
0941dedb70 Remove unused src/x86_64/Lis_signal_frame.c 2012-09-28 14:06:07 +03:00
Tommi Rantala
5d0f376b08 Invert tdep_init() flag logic
Invert the flag that signals that tdep_init() was called, to move the
symbol from data to BSS.
2012-09-28 14:06:07 +03:00
Konstantin Belousov
d0cbc51955 x86_64: stop unwinding when %rbp location is NULL 2012-09-21 23:06:17 -07:00
ariel.burton@roguewave.com
d00b621090 PATCH: fix build with --enable-msabi-support
This attached patch, relative to libuninwd-1.0.1,
will fix building with --enable-msabi-support on linux x86_64.

Ariel Burton
2012-09-15 10:47:34 -07:00
Tommi Rantala
5fef17c05d Fix memory leaks in unw_create_addr_space() wrong-endian error paths
Check the endianness earlier in unw_create_addr_space() on all
architectures to avoid leaking the dynamically allocated address space
struct.

This was already fixed for ARM in commit cf6a998796 ("Fix memory leak
in ARM unw_create_addr_space()"). Move the endianness check also on ARM
to avoid malloc() & free() in the error case.
2012-08-21 22:33:29 +03:00
Arun Sharma
dd297ea92e Revert "x86_64: unbreak test-ptrace"
This reverts commit c9c5a40be1.
dwarf_get() returns 0 on success. We should continue unwinding
in that case.

TBD: investigate test-ptrace failure on some platforms.
2012-05-18 15:24:02 -07:00
Arun Sharma
c9c5a40be1 x86_64: unbreak test-ptrace
If dwarf_get returns 0 (indicating the end of call chain), we should
not override the return value to 1. This may result in the caller
continuing to unwind and getting spurious errors.
2012-05-16 07:49:30 -07:00
Konstantin Belousov
1a6ea3da60 freebsd: Fix boundary conditions for non-dwarf walker on x86_64.
In the commit d04dc94cc2, the check for
dwarf.ip == 0 was removed from non-dwarf walker in x86_64 version of
unw_step(). Apparently this broke the detection of the end of frame
chain when NULL %rbp is specified, because the case just marked
dwarf.ip as 0. Explicitly set ret to 0 to indicate the end of
iteration.
2012-05-14 23:18:00 -07:00
Konstantin Belousov
3bb74aae3d freebsd: Account for the possible ERESTART handling of the syscalls. 2012-05-14 23:07:52 -07:00
Arun Sharma
d04dc94cc2 dwarf: ip == 0 should't terminate unwind 2012-03-25 18:10:10 -07:00
Arun Sharma
52ca68c770 Fix a race condition
There is a window of time between the munmap and the tls_cache being
marked as destroyed, where there could be a bad access to memory that
has been unmapped/freed. Reorder the code a bit to close the window.

Signed-off-by: Paul Pluzhnikov <ppluzhnikov@google.com>
2011-12-16 10:45:51 -08:00
Arun Sharma
cf2f3d3b75 Correct the inverted check
Typo when manually applying the previous commit.
2011-12-02 08:35:00 -08:00
Arun Sharma
2f328202ee Fix a compiler warning
Signed-off-by: Paul Pluzhnikov <ppluzhnikov@google.com>
2011-12-01 22:08:08 -08:00
Arun Sharma
1010880548 Address x86_64 crashes when using sigaltstack
The crashes were tracked down to f->rpb_cfa_offset being incorrect.

The problem is that {rsp,rbp}_cfa_offset only have 15 bits, but for
SIGRETURN frame they are filled with:

// src/x86_64/Gstash_frame.c

   f->cfa_reg_offset = d->cfa - c->sigcontext_addr;
   f->rbp_cfa_offset = DWARF_GET_LOC(d->loc[RBP]) - d->cfa;
   f->rsp_cfa_offset = DWARF_GET_LOC(d->loc[RSP]) - d->cfa;

The problem is that the delta here can be arbitrarily large when
sigaltstack is used, and can easily overflow the 15 and 30-bit fields.

When signal handler starts running, the stack layout is:

 ... higher addresses ...
        ucontext
 CFA->
        __restore_rt (== pretcode in rt_sigframe from
                      linux-2.6/arch/x86/include/asm/sigframe.h)
 SP ->
       ... sighandler runs on this stack.

 ... lower addresses ...

This makes it very convenient to find ucontext from the CFA.

Attached patch re-tested on Linux/x86_64, no new failures.

Signed-off-by: Paul Pluzhnikov <ppluzhnikov@google.com>
Reviwed-by: Lassi Tuura <lat@cern.ch>
2011-11-27 18:34:38 -08:00
Arun Sharma
0a26727ea2 Fix TLS destructor ordering problems
Glibc calls thread-specific dtors in the order in which the keys were added,
so the first dtor is the trace_cache_free() one. Then thread-specific
data for some other key is free()d, which calls into unw_backtrace(),
which uses dangling cache and munmapped cache->frames.

[ Minor rename + compiler warning fix: asharma@fb.com ]
Signed-off-by: Paul Pluzhnikov <ppluzhnikov@google.com>
2011-10-29 17:12:36 -07:00
Arun Sharma
08077a4962 pthread_once() workaround for FreeBSD and Solaris
On FreeBSD, as well as on the Solaris < 10, weak pthread_once stub is
always exported from libc. But it does nothing, which means that if
threaded library is not loaded, then pthread_once() call do not actually
call the initializer finction. The construct
  if (likely (pthread_once != 0))
  {
    pthread_once(&trace_cache_once, &trace_cache_init_once);
then fails to initialize the trace cache on x86_64.

Work around by checking that the initializer was indeed called.
Note that this can break if libthr is loaded dynamically, but my belief
is that there is no platforms which allow dynamic loading of the threading
library.
2011-10-29 16:53:30 -07:00
Arun
f89fb17695 Fix incorrect calls to memset.
Found when compiling libunwind with clang.

Signed-off-by: Paul Pluzhnikov <ppluzhnikov@google.com>
2011-10-02 22:43:28 -07:00
Arun Sharma
e09f9701ff Handle register nums > 16 on x86_64
gcc generates them when using ms-abi. Support disabled by
default since it increases the cache footprint of the library.
2011-06-18 20:48:49 -07:00