Commit 7d43108f9c ("No
libunwind-generic.so if configured with --disable-shared") introduced a
check to avoid creating a broken libunwind-generic.so link, but the
result of the commit is that libunwind-generic.so is never created (at
least when installing to a clean directory).
We need to check for the installed libunwind-$(arch).so file,
libunwind-generic.so will be the symbolic link name.
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>
Commit 297d9cd07d (Fix for failing test-setjmp)
breaks non glibc systems, since __GLIBC_PREREQ is not defined there.
As a consequence, preprocessor aborts with an error.
Trying to hide __GLIBC_PREREQ under #ifdef __GLIBC would require
either code duplication, or moving the longjmp implementation into
the separate file, which is included twice. In fact, I am not sure
in any use of the __GLIBC_PREREQ at the compile time, because the
compiled code can be run on the later version of glibc.
Below is the patch, tested on FreeBSD x86/x86_64 and Scientific Linux 6.1
x86_64. I compile the code always, but keep it in under unused static
symbol. In principle, the code could be optimized out by linker.
[ Minor formatting edits: asharma@fb.com ]
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>
On Mon, Nov 14, 2011 at 5:02 PM, Paul Pluzhnikov <ppluzhnikov@google.com> wrote:
> P.S. test-setjmp is failing for me (before or after the patch).
> When I enable assertions (to confirm my new assertions are correct), I see:
>
> lt-test-setjmp: ../../src/dwarf/Gparser.c:754: apply_reg_state: \
> Assertion `rs->reg[17].where == DWARF_WHERE_EXPR' failed.
>
> which likely explains that failure.
The problem is actually two-fold:
First, the loops in {sig,}longjmp.c are "do { ... } while (unw_step() >= 0);"
But unw_step() returns 0 on reaching the end of the chain (_start),
and the loop should stop there.
The second problem is that with this commit:
c67da0b50e
glibc obfuscates value of SP in jmp_buf, so we might as well just give up.
Patch attached.
Thanks,
--
Paul Pluzhnikov
The ARM EABI does not use the .eh_frame and .eh_frame_hdr sections for unwinding. Therefore it doesn't make sense to call dwarf_step if CONFIG_DEBUG_FRAME is not defined.
Define unw_tdep_context rather than using ucontext_t in order to support
systems that lack ucontext.h. Note that POSIX.1-2008 removed getcontext,
makecontext and swapcontext from its specification.
Signed-off-by: Ken Werner <ken.werner@linaro.org>
Since the dl_iterate_phdr is required for local unwinding only the use of
struct dl_phdr_info can be eliminated in case libunwind gets compiled for
remote unwinding. This enhances libunwinds portability to targets that
don't provide any dl_iterate_phdr functionality.
Signed-off-by: Ken Werner <ken.werner@linaro.org>
Exclude <link.h> because it is only required for local unwinding when
iterating over the program headers.
Have the following DWARF related functions available in case of
UNW_REMOTE_ONLY because they are used by libunwind-ptrace:
dwarf_find_debug_frame
locate_debug_info
find_binary_for_address
load_debug_frame
debug_frame_tab_new
debug_frame_tab_append
debug_frame_tab_shrink
debug_frame_tab_compare
Signed-off-by: Ken Werner <ken.werner@linaro.org>
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>
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.
This keeps the definition on IA64 and all the other architectures in sync with
the declaration of _UPTi_find_unwind_table. This also mimics the behaviour of
what's done for local unwinding and allows the function to provide more than
one way to undwind.
Signed-off-by: Ken Werner <ken.werner@linaro.org>
In case the user doesn't specify whether to unwind using the ARM specific
unwind tabler or DWARF info libunwind should prefer the latter. Since DWARF
expressions are more powerful than the ARM specific unwind tables
arm_find_proc_info is changed to check for DWARF first.
Signed-off-by: Ken Werner <ken.werner@linaro.org>
Prevents unw_step from trying to unwind the stack using the ARM specific
unwind tables in case the DWARF based unwinding was successful.
Signed-off-by: Ken Werner <ken.werner@linaro.org>
Initialize the return value with -1 in order prevent arm_find_proc_info from
returning zero. This could happen in case the environemtn variable
UNW_ARM_UNWIND_METHOD doesn't allow exidx and/or dwarf unwinding.
Signed-off-by: Ken Werner <ken.werner@linaro.org>
Change _UPTi_find_unwind_table to also look for the ARM specific unwind
information. Adjust the ARM unwind code to read memory using the accessor
routines.
Signed-off-by: Ken Werner <ken.werner@linaro.org>
Rename the dwarf dl_iterate_phdr callback routine and the callback_data
structure to dwarf_callback and dwarf_callback_data. Make it available
within libunwind by declaring the two at the dwarf.h header file.
Signed-off-by: Ken Werner <ken.werner@linaro.org>
A previous change reduced the number of arguments that this function
tasks, but one call at least did not get updated, resulting in a build
failure on ia64-linux. This patch fixes it.
On ia64-hpux version 11.31, <sys/ptrace.h> has been removed.
This patch adds a configure check for this header file, and only
includes <sys/ptrace.h> if it exists.
This patch add support for resuming at a certain stack frame even if signal
frames are involved. For restoring the registers the trampoline (sigreturn)
is used. RT and non-RT signal frames are handled for both >=2.6.18 and
<2.6.18 kernels.
Signed-off-by: Ken Werner <ken.werner@linaro.org>
This patch adds a few more patterns to the check that detects if the IP
points to a sigreturn sequence.
Signed-off-by: Ken Werner <ken.werner@linaro.org>
Insert static branch prediction predicates in useful places and avoid
unnecessary code in the hottest paths. Bypass unnecessary indirect
calls, in particular to access_mem(), when known to be safe.
Since the fast unwinding code path doesn't need the full context,
a faster target dependent getcontext is implemented.
Signed-off-by: Lassi Tuura <lat@cern.ch>
In order to have the DWARF_* macros working properly a generic and a local
variant of the ex_tables.c have been created.
Signed-off-by: Ken Werner <ken.werner@linaro.org>
Dropping the extra frame for unw_backtrace itself using unw_step is
approximately 15% slower than skipping the frame in tdep_trace. So
drop the frame in the latter, and make the function a private
implementation detail for libunwind, not an exported interface.
Also moves unw_getcontext call back into unw_backtrace to avoid an
extra call frame in case slow_backtrace does not get inlined into
unw_backtrace.
Adds new function to perform a pure stack walk without unwinding,
functionally similar to backtrace() but accelerated by an address
attribute cache the caller maintains across calls.
Usually we don't have a valid location for the SP but we keep calculating
the value of the CFA. The ARM backend should return this value instead.
Signed-off-by: Ken Werner <ken.werner@linaro.org>
Using malloc is not an option since unw_init_local and unw_step are supposed
to be async signal safe. Therefore this code path can be removed.
Signed-off-by: Ken Werner <ken.werner@linaro.org>
There is no need for libunwind to set/fake a name of the elf file from which
the program header came from.
Signed-off-by: Ken Werner <ken.werner@linaro.org>
DWARF expressions are more powerful than the ARM specific unwind tables.
Therefore DWARF should be the preferred unwind method.
Signed-off-by: Ken Werner <ken.werner@linaro.org>
Move code that does not necessarily need to reside in the ex_tables.h header
file into ex_tables.c. Add comments and remove unused code.
Signed-off-by: Ken Werner <ken.werner@linaro.org>
This eliminates the arm_stackframe and therefore the need to synchronize the
two models. It also clears the way for unwinding call stacks with mixed
DWARF- and extbl-frames.
Signed-off-by: Ken Werner <ken.werner@linaro.org>
Uses ex_tables routines to provide a new means of unwinding the stack.
Set UNW_ARM_UNWIND_METHOD=4 to use ARM-specific unwinding tables.
Signed-off-by: Ken Werner <ken.werner@linaro.org>
Implements a check for call to sigreturn that the kernel will have
setup before jumping to the signal handler.
Signed-off-by: Ken Werner <ken.werner@linaro.org>
If mmap fails, be sure to close the maps file before returning an error.
Signed-off-by: Zachary T Welch <zwelch@codesourcery.com>
Signed-off-by: Ken Werner <ken.werner@linaro.org>
This prevents the linker from complaining about a missing symbol when
building the test-setjmp test case.
Signed-off-by: Ken Werner <ken.werner@linaro.org>
in elf_map_image() to ensure mapped files have a valid ELF header.
Signed-off-by: Zachary T Welch <zwelch@codesourcery.com>
Signed-off-by: Arun Sharma <asharma@fb.com>
Eliminates obfuscating variables in favor of adding files directly
to library SOURCES. Eliminates the need for EXTRA_DIST variable.
Signed-off-by: Zachary T Welch <zwelch@codesourcery.com>
Rather than building the sources directly, create a library that
gets linked statically into libunwind.la and libunwind-$(arch).la.
Signed-off-by: Zachary T Welch <zwelch@codesourcery.com>
Build DWARF source files into automake convenience libraries to
eliminate duplication in arch-dependent library build rules.
Adds a configure-time check to determine whether to use them.
Signed-off-by: Zachary T Welch <zwelch@codesourcery.com>
Eliminate redundant listing of libunwind_setjmp source files by
using automake's '+=' operator.
Signed-off-by: Zachary T Welch <zwelch@codesourcery.com>
Frees newly created address space memory in the event of a failure
caused by an endian mismatch.
Signed-off-by: Zachary T Welch <zwelch@codesourcery.com>
Current implementation fails to find separate debug symbols when
.gnu_debuglink is set to the same name of the target ELF basename
(e.g. "libc.so.6" for /lib/libc.so.6). This patch fixes this by ignoring
separate debug files that contain a .gnu_debuglink section.
It also fixes a small typo in a related Debug() line.
Signed-off-by: Andris Zeila <andris.zeila@accenture.com>
the instruction after the call for a normal frame. libunwind uses
IP-1 to lookup unwind information. However, this is not necessary for
interrupted frames such as signal frames (or interrupt frames) in
the kernel context.
This patch handles both cases correctly.
Based on work by Mark Wielaard <mwielaard@redhat.com>
FreeBSD-supplied setjmp() saves incremented stack pointer into jmpbuf.
I have no idea whether siglongjmp ever worked on amd64, since
UNW_NUM_EH_REGS == 2 and abort at siglongjmp.c:81 is firing.
This is rather on the obvious side.
While doing strace on an executable using libunwind, I noticed a
lot of:
msync(0, 1, MS_SYNC) = -1 ENOMEM (Cannot allocate memory)
Since we know that the first page isn't mapped (or at least doesn't
contain the data we are looking for), we can eliminate all such
msync calls.
Tested on Linux/x86_64 with no regressions.
Original code was accessing rs_cache memory without holding a lock
in some cases. If there was sufficient cache pressure, entry being
accessed may be overwritten by another thread, resulting in a data
race.
We now make a thread local copy of the data, before releasing the
lock. If we end up supporting UNW_CACHE_PER_THREAD properly
in the future, this memcpy should be unnecessary.
Greetings,
Attached patch gets rid of additional unnecessary branch (rs_get_cache
can not return NULL unless caching_policy is UNW_CACHE_NONE), gets rid of
goto's, and makes apply_reg_state (major CPU consumer) execute with cache
lock not held (before the patch, apply_reg_state was called with lock held
for newly-inserted entries, but not for found-in-cache entries).
Tested on Linux/x86_64 with no regressions.
Thanks,
--
Paul Pluzhnikov
Greetings,
Attached patch is rather on the obvious side:
- rs1 can't be NULL since it's assigned on previous line
- rs_new never returns NULL, and if it ever did, we'd crash on memcpy that
preceeds the NULL check.
Tested on Linux/x86_64 with no regressions.
Thanks,
--
Paul Pluzhnikov
Currently, libunwind allocates several PATH_MAX entries on stack, while
trying to find a binary via /proc/.../maps.
However stack space may be at premium (especially when sigaltstack is used),
and PATH_MAX on Linux is 4096, while SIGSTKSZ is only 8192 on x86.
Attached patch eliminates multiple PATH_MAX stack allocations, and simplifies
code in maps_next, at the cost of being unable to do anything if we can't
mmap one page. It appears to me that under such low-memory conditions,
libunwind will fail shortly elsewhere anyway.
This patch also disables more of debug_frame-handling code when
CONFIG_DEBUG_FRAME is undefined.
Tested on Linux/x86_64 with and without CONFIG_DEBUG_FRAME, no regressions.
The behavior on wait vs abort unwind depends on the locking primitive
chosen by the user. This makes the API consistent and independent of
the locking primitive.
Greetings,
We use libunwind just for stack traces (I suspect many others do as well).
The use pattern is:
GetStackTrace(void** result, int max_depth)
{
...
unw_getcontext(&uc);
unw_init_local(&cursor, &uc);
while (n < max_depth) {
if (unw_get_reg(&cursor, UNW_REG_IP, (unw_word_t *) &ip) < 0) {
break;
}
result[n++] = ip;
if (unw_step(&cursor) <= 0) {
break;
}
}
Given this usage, it is quite convenient for us to block signals (or
prevent signal handlers from re-entering libunwind by other means) at the
"top level", which makes most of the sigprocmask calls performed by
libunwind itself unneccessary.
The second patch in this series adds a configure option which removes most
of the sigprocmask calls.
Attached patch is a preliminary for it -- consolidating all of the
"sigprocmask; mutex_lock;" sequences into lock_acquire and "mutex_unlock;
sigprocmask;" sequences into lock_release.
Thanks,
--
Paul Pluzhnikov
commit 402d15b123d54a7669db7cf17a76dd315094e472
Author: Paul Pluzhnikov <ppluzhnikov@google.com>
Date: Mon Sep 21 10:18:28 2009 -0700
Replace "sigprocmask + mutext_lock" with a single lock_acquire.
Likewise, replace "mutext_unlock + sigprocmask" with lock_release.
This rule (no IP adjustment on ia64) may be correct for locating the right FDE.
Unfortunately the same adjusted/unadjusted return address is being used also by
__gxx_personality_v0() to locate the right call-site (the try {} block) for
unwinding. And this case is already sensitive for off-by-one PC values.
Unlike the FDE location where the function prologue + epilogue make it immune
against off-by-one PC calculations.
Therefore suggesting to unify it with non-ia64 case.
Signed-off-by: Jan Kratochvil <jan.kratochvil@redhat.com>
Provide a special implementation for ia64, because the unwind
information is such that an IP adjustment is not necessary before
looking up unwind info.
Bad things happen if libunwind only provides parts of the ABI and
the rest come from libgcc.
Signed-off-by: Jan Kratochvil <jan.kratochvil@redhat.com>
getcontext in libc.
Also cleanup the namespace (check-name-space passes on x86_64 now).
Replace uses of offsets.h with ucontext_i.h.
Rename _x86_64_setcontext to _Ux86_64_setcontext.
TBD: Add CFI annotations for get/setcontext.
Signed-off-by: Paul Pluzhnikov <ppluzhnikov@google.com>
Signed-off-by: Arun Sharma <arun.sharma@google.com>
bad/missing unwind information, which could result in libunwind
dereferencing bad pointers. This mechanism is based on msync(2) system
call and significantly reduces the chances of a bad pointer
dereference in libunwind.
The original idea was to turn this mechanism on only when necessary
i.e. libunwind didn't find proper unwind information for a IP.
There are a couple of problems in the current implementation.
* The flag is global and is modified without locking
* The flag isn't reset when starting a new unwind
The attached patch makes ->validate a per-thread setting by moving it
into struct cursor from unw_local_addr_space and resets it to false
when starting a new unwind. As a result, cursor->as_arg points to the
cursor itself instead of the ucontext (for the local case).
This was found to reduce the number of msync() system calls from an
application using libunwind significantly.
Signed-off-by: Paul Pluzhnikov <ppluzhnikov@google.com>
Signed-off-by: Arun Sharma <arun.sharma@google.com>
* src/arm/unwind_i (arm_lock, arm_local_resume): Define.
* src/ptrace/_UPT_find_proc_info.c: Handle ARM like X86 etc.
* tests/flush-cache.S (flush_cache): Add (dummy) ARM-version.
ARM does need executable stack, even on Linux...
Signed-off-by: Anderson Lizardo <anderson.lizardo@indt.org.br>
Signed-off-by: Bruna Moreira <bruna.moreira@indt.org.br>
The current pattern is too restrictive and doesn't work well on
modern glibcs.
Signed-off-by: Paul Pluzhnikov <ppluzhnikov@google.com>
Signed-off-by: Arun Sharma <arun.sharma@google.com>
* Use explicit types for XMM registers
* Support full width (128 bits) access
Signed-off-by: Andrew Cagney <cagney@redhat.com>
Signed-off-by: Arun Sharma <aruns@google.com>
as "weak". Since the elf-support is in the library anyhow, this serves
no purpose and in fact causes problem because the weak reference alone
is not enough to pull in the ELF-code from an archive file, causing to
spurious failures of get_proc_name.
On some systems executable stacks are denied. Since libunwind and the
tests don't actually need executable stacks this patch marks all
assembly files as not needing it.
The original patch comes from frysk:
2007-04-05 Jan Kratochvil <jan.kratochvil@redhat.com>
* src/hppa/getcontext.S, src/hppa/setcontext.S, src/hppa/siglongjmp.S,
src/ia64/Ginstall_cursor.S, src/ia64/Linstall_cursor.S,
src/ia64/dyn_info_list.S, src/ia64/getcontext.S, src/ia64/longjmp.S,
src/ia64/setjmp.S, src/ia64/siglongjmp.S, src/ia64/sigsetjmp.S,
src/ppc64/longjmp.S, src/ppc64/siglongjmp.S, src/x86/longjmp.S,
src/x86/siglongjmp.S, src/x86_64/longjmp.S, src/x86_64/setcontext.S,
src/x86_64/siglongjmp.S: Stack should be non-executable, for SELinux.
I added a couple more markers for new files in current libunwind.
Before this patch you would get the following on selinux enabled
systems without allow_exec_stack: error while loading shared
libraries:
libunwind.so.7: cannot enable executable stack as shared object
requires: Permission denied
After the patch that error disappears and all test results are similar
to the results on systems without executable stack protection.
routine and add address-space argument. This is needed because on
PPC64, a the function-name symbol refers to a function descriptor
(unlike, for example, on ia64, where the @fptr() operator is needed to
refer to a function descriptor). Thus, in order to look up the name
of a function, we need to dereference the function descriptor. To
make matters more "interesting", the function descriptors are normally
resolved by the dynamic linker, so we can't get their values from the
ELF file. Instead, we have to read them from the running image, hence
the need for the address-space argument.
This is so that the source file gets distributed and _ucontext_i.h is
generated properly on the target machine.
Signed-off-by: Arun Sharma <arun.sharma@google.com>
When libunwind is linked with a C++ program that throws exceptions,
the exception that's thrown is passed in %rax. However, libc's
setcontext clears %rax, causing problems.
This patch implements a setcontext that doesn't clobber rax.
TBD: Add dwarf CFI annotations
Signed-off-by: Arun Sharma <arun.sharma@google.com>
Yes, it casts to signed, but then converts right back to
unsigned via the return type. Fixed thus.
Signed-off-by: Richard Henderson <rth@redhat.com>
Signed-off-by: Arun Sharma <arun.sharma@google.com>
CFA should be incremented by 16 in the hope that the previous frame
may have valid unwind info.
Also increase the default frame pointer recognition heuristic from 4k
to 16k.
Signed-off-by: Andrey Veskov <Andrey.Veskov@intel.com>
Signed-off-by: Arun Sharma <arun.sharma@google.com>
Now that dwarf_find_save_locs() not just finds the save-locations but
also updates the cursor-state, document this fact (the function really
is misnamed now).
Be sure to clear pi->unwind_info when looking up the kernel table and
not needing the unwind-info. Otherwise, _UPT_put_unwind_info() may
erroneously call free() on the pointer, even though that space wasn't
malloc'd, leading to crashes..
(maps_next): After reading less than a full buffer of data, copy
remaining data to the top of the buffer so as to maintain the
invariant that all data between mi->buf and mi->buf_end is valid.
This avoids maps_next() parsing uninitialized data.
(get_initial_stack_pointers): Likewise.
(unw_init_local): Use new functions to make code more readable and add
Linux kernel support.
(Logical change 1.296)