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
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.
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.
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>
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>
Hi,
there is a compilation issue with Clang and latest libunwind - It's
about "typedef struct unw_tdep_save_loc" and one more struct:
include/libunwind-x86_64.h:111:9: error: empty struct has size 0 in C,
size 1 in C++ [-Werror,-Wextern-c-compat]
The solution is very simple:
Ubuntu's libc-bin (2.15-0ubuntu20.2) on x86_64 uses DW_CFA_val_expression
in describing the pthread spinlock operations __lll_unlock_wake() and
__lll_lock_wait(). libunwind 1.1 doesn't understand that opcode and
so backtraces from those operations are truncated.
This changeset adds basic support for it, by adding a new type to
dwarf_loc_t that describes the register's actual contents rather than
its location. I've only implemented the new type for x86_64, and
stubbed it out for all other architectures -- it looks like a lot
of that code is duplicated so oughtn't to be that hard, but I don't
have test cases for them.
Tested that DW_CFA_val_expression works on x86_64 (by using
https://code.google.com/p/gperftools/ on a lock-heavy program).
Build-tested on x86, x86_64 and arm. The unit tests don't pass for me
on any of those archs, but this cset doesn't break anything that was
passing before.
Signed-off-by: Tim Deegan <tjd@phlegethon.org>
This patch adds support for the powerpc64le-linux platform. It consists
of two main features:
- Support little-endian byte order
This is done via a "big_endian" member of struct unw_addr_space,
which is evaluated by common code via the dwarf_is_big_endian
macro, and also in endian-aware code in unw_is_signal_frame.
- Support the ELFv2 ABI
This is done via an "abi" member of struct unw_addr_space. This
is currently only needed in tdep_get_func_addr, since the ELFv2
ABI does not use function descriptors.
Both new members are initialized in unw_create_addr_space and
ppc64_local_addr_space_init, following the mips precedent.
Since ppc32 and ppc64 now no longer share the unw_create_addr_space
implementation, the file is duplicated from the ppc directory into
ppc32/ppc64.
Tested on powerpc64-linux and powerpc64le-linux. Support on LE
seems to be as good as existing BE support; I have not attempted to
fix the existing shortcomings of PPC support that already cause a
number to tests to fail due to unimplemented features.
Signed-off-by: Ulrich Weigand <uweigand@de.ibm.com>
This change adds some special cases to allow libunwind to compile
for QNX.
* QNX's copy of <elf.h> and <link.h> reside in sys/ instead. To deal
with this, an AC_CHECK_HEADERS() was added to check for the files
in both locations.
* Similarly, QNX does not have <endian.h>. In cases where the file is
not found, logic was added to refer to QNX-specific macros to determine
endianness.
* The QCC compiler, which is a wrapper around GCC, cannot handle some
standard GCC options. Therefore, logic was added to check for QCC,
and when it is found, to suppress the use of -lgcc, and to express the
option -nostartfiles as -Wc,-nostartfiles instead, which is correctly
passed on to the underlying GCC.
* Finally, the support file os-qnx.c was added, patterned after the existing
os-*.c files. Only local image lookup is currently supported (see the
comments for more information), but this is sufficient for QNX, since
ptrace is not supported there anyway, and that is the only case where the
function is required to do remote image lookup.
Change-Id: Ie7934f94a7317bdde59335f2acd4c3a97c0384c1
When libunwind is built for a ppc32 target, for example the yocto distro
for qemuppc, and configured with options --enable-debug-frame and
--enable-debug, then the shortfall in the size of the 'opaque' member
of the unw_cursor_t type throws an assert in mi_init().
The calculations for the ppc32 target size of UNW_TDEP_CURSOR_LEN in
the comment block based on the register count plus overhead sum to 280
words. However, that value is not reflected in the ppc32 header, which
defines the size as 200. Fixing the ppc32 header value to 280 makes the
unw_cursor_t type larger than struct cursor type and the assert tests
true at run-time in mi_init().
Signed-off-by Dave Lerner <dave.lerner@windriver.com>
src/ptrace/_UPT_find_proc_info.c: In function 'get_unwind_info':
src/ptrace/_UPT_find_proc_info.c:67: warning: implicit declaration of function 'ia64_find_unwind_table'
Add support for the 32bit SuperH architecture running Linux.
Specifically, support is added for SH4, and support for earlier SH
versions and to the 64bit SH5 are left out. This was tested in qemu with
a little-endian SH4 debian image & GCC 4.7 cross compiler.
Add MIPS support to the coredump library. Explicit support for the MIPS
program counter register is added so that we can start backtracing from
the program counter value we read from a core dump. The PC register
support was not strictly required for local backtracing, and we will in
fact just plug the return address to the PC register in getcontext().
I have only tested the 32bit "OABI" paths.
We can use the __sync builtin atomics also on other architectures than
IA64. GCC 4.7 documentation notes that these builtins are ``legacy'' --
adding support for the newer GCC __atomic atomics should be fairly easy.
Instead of maintaining a pointer to the `sos_memory' array, maintain an
index that tells the next free position. When atomic operations are
available, the allocation boils down to a single fetch-and-add
operation.
Rename the `ALIGN' macro to `UNW_ALIGN', and move it from
`_UCD_internal.h' to `libunwind_i.h' so that we can share it with the
mempool code. `ALIGN' was clashing with system headers on FreeBSD:
In file included from src/coredump/_UCD_access_reg_freebsd.c:26:
src/coredump/_UCD_internal.h:102:1: warning: "ALIGN" redefined
In file included from /usr/include/sys/param.h:115,
from src/coredump/_UCD_lib.h:52,
from src/coredump/_UCD_access_reg_freebsd.c:24:
/usr/include/machine/param.h:79:1: warning: this is the location of the previous definition
For a few of the supported architectures we can use one-to-one mapping
from the dwarf to the libunwind register numbers. Allow the
architectures to define their own dwarf_to_unw_regnum() macro to do this
easily.
In file included from mi/Lput_dynamic_unwind_info.c:4:
mi/Gput_dynamic_unwind_info.c:48:40: error: macro "tdep_put_unwind_info" passed 3 arguments, but takes just 2
- Add tdep macro for {dwarf,ia64}_find_unwind_table so that ia64
doesn't try to use dwarf code.
- Fix extraneous #if.
- Fix mistyped filename in Makefile.am.
- Link ia64-specific tests with correct libraries.
Signed-off-by: Martin Milata <mmilata@redhat.com>