After successfully stepping the cursor on ARM, the proc info is
invalidated only in dwarf_step(). Invalidate the proc info also when
stepping with the non-dwarf based methods. This fixes
unw_get_proc_info() returning stale data.
The core dump unwinder can be used for demonstrating the bug. When
unwinding based only on DWARF data, the proc info is correct:
$ UNW_ARM_UNWIND_METHOD=1 ./test-coredump-unwind core `cat backing_files` 2>/dev/null
ip=0x000086d8 proc=000086d4-000086dc handler=0x00000000 lsda=0x00000000
ip=0x000086ef proc=000086dc-000086f2 handler=0x00000000 lsda=0x00000000
ip=0x000086e7 proc=000086dc-000086f2 handler=0x00000000 lsda=0x00000000
ip=0x00008597 proc=00008584-0000859a handler=0x00000000 lsda=0x00000000
ip=0x76e3ac3b proc=76e3aba0-76e3acec handler=0x00000000 lsda=0x00000000
When unwinding based only on the exidx method, we see the proc info
lagging behind:
$ UNW_ARM_UNWIND_METHOD=4 ./test-coredump-unwind core `cat backing_files` 2>/dev/null
ip=0x000086d8 proc=000086d4-000086db handler=0x00000000 lsda=0x00000000
ip=0x000086ef proc=000086d4-000086db handler=0x00000000 lsda=0x00000000
ip=0x000086e7 proc=000086dc-000086f3 handler=0x00000000 lsda=0x00000000
ip=0x00008597 proc=000086dc-000086f3 handler=0x00000000 lsda=0x00000000
ip=0x76e3ac3b proc=00008584-0000859b handler=0x00000000 lsda=0x00000000
ip=0x000085c3 proc=76e3aba0-76e3ae4b handler=0x00000000 lsda=0x00000000
Finally, with this patch applied, we get the desired proc info also with
the exidx unwinder:
$ UNW_ARM_UNWIND_METHOD=4 ./test-coredump-unwind core `cat backing_files` 2>/dev/null
ip=0x000086d8 proc=000086d4-000086db handler=0x00000000 lsda=0x00000000
ip=0x000086ef proc=000086dc-000086f3 handler=0x00000000 lsda=0x00000000
ip=0x000086e7 proc=000086dc-000086f3 handler=0x00000000 lsda=0x00000000
ip=0x00008597 proc=00008584-0000859b handler=0x00000000 lsda=0x00000000
ip=0x76e3ac3b proc=76e3aba0-76e3ae4b handler=0x00000000 lsda=0x00000000
ip=0x000085c3 proc=0000859c-00008613 handler=0x00000000 lsda=0x00000000
Implement the Linux version of _UCD_access_reg() for ARM. We can
sidestep the register number remapping, as the libunwind register
numbers match one-to-one to the ELF core file register numbers.
Just pass potentially NULL pointers to free() in the error path in
load_debug_frame(). Saved 40 bytes of code in libunwind.so on ARM -O2
thumb build at the expense of slightly slower execution.
Stop pretending that unw_get_proc_info() works on PPC, and instead give
an error back to the caller. As far as I can tell, none of the libunwind
tests clear out the `unw_proc_info_t' before passing it to
unw_get_proc_info(), so they would end up working on garbage data.
ppc32/Gstep.c:116: warning: comparison between pointer and integer
ppc32/Gstep.c:116: warning: comparison with string literal results in unspecified behavior
ppc32/Gstep.c:116: warning: initialization makes integer from pointer without a cast
ppc32/Gstep.c:116: warning: passing argument 2 of 'fprintf' makes pointer from integer without a cast
/usr/powerpc-linux-gnu/include/stdio.h:333: note: expected 'const char *__restrict__' but argument is of type 'int'
Fix bitrot in HPPA common_init(). This has only been compile tested.
hppa/init.h: In function 'common_init':
hppa/init.h:33: error: 'struct cursor' has no member named 'ip_loc'
hppa/init.h:33: warning: implicit declaration of function 'HPPA_REG_LOC'
hppa/init.h:34: error: 'struct cursor' has no member named 'sp_loc'
hppa/init.h:36: warning: implicit declaration of function 'hppa_get'
hppa/init.h:36: error: 'struct cursor' has no member named 'ip_loc'
hppa/init.h:36: error: 'struct cursor' has no member named 'ip'
hppa/init.h:40: error: 'struct cursor' has no member named 'sp'
When cross-compiling libunwind with optimizations (-O1 or higher),
gcc-4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) optimizes away the memory
writes prior to the inline asm() statement in arm_local_resume() in the
non-signal-frame path, causing the `regs' array to be only allocated on
the stack, but not populated. This means that we are restoring garbage
to the registers.
As suggested in the GCC docs, add a fixed size input memory constraint
for the array content. This is enough to get the desired code to be
generated.
Adding __builtin_unreachable() to the point that we should never reach
was also in itself enough to inhibit the optimization. It also reduces
the function size by a few instructions.
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.
Properly export the symbol names also on MIPS. `make check' was
complaining:
src/.libs/libunwind.a(Linit.o): In function `mips_local_addr_space_init':
src/mips/Ginit.c:183: multiple definition of `mips_local_addr_space_init'
../src/.libs/libunwind-mips.a(Ginit.o):src/mips/Ginit.c:183: first defined here
src/.libs/libunwind.a(Lglobal.o): In function `_ULmips_init':
src/mips/Gglobal.c:42: multiple definition of `mips_lock'
../src/.libs/libunwind-mips.a(Gglobal.o):src/mips/Gglobal.c:42: first defined here
collect2: ld returned 1 exit status
After searching the normal symbol table, look if the binary contains
.gnu_debugdata section. If it does, run LZMA decompression on it, load
the resulting ELF image into memory and call lookup_symbol() on it
again.
lookup_symbol() is modified so that it takes min_dist as a parameter and
only returns a symbol when it finds one that is closer than indicated by
the parameter.
Signed-off-by: Martin Milata <mmilata@redhat.com>
The code for symbol lookup (elfxx.c:lookup_symbol) works by iterating
over symbol tables while maintaing the symbol closest to the supplied
instruction pointer. Whenever this search encountered symbol that was
longer than result buffer, the function returned -UNW_ENOMEM even though
the final symbol wasn't too long.
Signed-off-by: Martin Milata <mmilata@redhat.com>
dwarf/Gfind_unwind_table.c: In function '_Ux86_dwarf_find_unwind_table':
dwarf/Gfind_unwind_table.c:223:46: error: 'struct elf_dyn_info' has no member named 'edi'
Fixup commit d93d96ad83 ("Fix compilation
on IA64"), and replace the dwarf_find_unwind_table() call with
tdep_find_unwind_table().
Fixes linkage error on IA64:
../src/.libs/libunwind-coredump.so: undefined reference to `dwarf_find_unwind_table'
Change the way we generate the cursor header files, so that we do not
need to invoke IA64 binaries, which would fail when cross-compiling
libunwind.
Adopt the strategy used in the Linux kernel build system, and parse our
annotated offset information from the assembler file produced by the
compiler.
- 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>
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.
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.
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.
Older kernels interpret the pid argument of the process information
sysctls as pid only. If libunwind UPT consumer passed tid to _UPT_create,
tdep_get_elf_image() returns error due to sysctls failure. Provide a
slow workaround by searching for a process owning the supplied tid if
sysctl returned ESRCH.
Currently the expression evaluation always succeeds,
and possible error is not propagated to the caller.
The ',' operator makes the condition always return 0.
Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Tested-by: Paul Pluzhnikov <ppluzhnikov@google.com>
ALIGN lets you align pointers and STRUCT_MEMBER lets you get
structure members at a specific offset.
These are useful in general, and will be needed for the coredump notes
cleanup work.