[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Libunwind-devel] Libunwind support for NULL IP
From: |
Arun Sharma |
Subject: |
Re: [Libunwind-devel] Libunwind support for NULL IP |
Date: |
Wed, 4 Apr 2012 20:45:15 -0700 |
On Tue, Apr 3, 2012 at 8:47 AM, Prabhat Verma
<address@hidden> wrote:
> I tried this fix but it seems to be broken in more ways than expected...
The test needed a couple of fixes too :) See below.
> I am sending you the test program for reference. For now, I set the IP to a
> non-null value and it seems to unwind all the way except that first two
> frames are lost i.e. if main() calls foo1() calls foo() calls
> do_null_fp_dereferece_and_segv(), then the generated stacktrace will show
> frames foo1 - main (do_null_fp.. and foo are lost)....
> That said, for us, this is still a big improvement over backtrace and the
> initial tests look exciting.
Were you compiling with -O2 by any chance? If so, that's to be expected.
00000000004016c0 <foo8()>:
4016c0: 55 push %rbp
4016c1: ba 0e 00 00 00 mov $0xe,%edx
4016c6: be 94 c4 40 00 mov $0x40c494,%esi
4016cb: bf 80 01 61 00 mov $0x610180,%edi
4016d0: 48 89 e5 mov %rsp,%rbp
4016d3: e8 78 fa ff ff callq 401150
4016d8: 5d pop %rbp
4016d9: e9 c2 ff ff ff jmpq 4016a0 <foo7()>
4016de: 66 90 xchg %ax,%ax
Notice that there is a jmp to foo7, not a call. That's called tail
call optimization. Try compiling with -fno-optimize-sibling-calls
-fno-omit-frame-pointer.
I get:
Stack Trace ----->
temp_ip = 4015dd, temp_sp = 7fff7f403018, procedure--> _Z3foov
temp_ip = 4015fd, temp_sp = 7fff7f403030, procedure--> _Z4foo1v
temp_ip = 40161d, temp_sp = 7fff7f403040, procedure--> _Z4foo2v
temp_ip = 40163d, temp_sp = 7fff7f403050, procedure--> _Z4foo3v
temp_ip = 40165d, temp_sp = 7fff7f403060, procedure--> _Z4foo4v
temp_ip = 40167d, temp_sp = 7fff7f403070, procedure--> _Z4foo5v
temp_ip = 40169d, temp_sp = 7fff7f403080, procedure--> _Z4foo6v
temp_ip = 4016bd, temp_sp = 7fff7f403090, procedure--> _Z4foo7v
temp_ip = 4016dd, temp_sp = 7fff7f4030a0, procedure--> _Z4foo8v
temp_ip = 4016fd, temp_sp = 7fff7f4030b0, procedure--> _Z4foo9v
temp_ip = 4012fd, temp_sp = 7fff7f4030c0, procedure--> main
temp_ip = 7fef6c05d30d, temp_sp = 7fff7f403220, procedure--> __libc_start_main
temp_ip = 40135d, temp_sp = 7fff7f4032e0, procedure--> _start
diff I used (for reference only. pasted patch. may not apply):
--- myFirstExp (1).cpp 2012-04-04 20:18:36.655767001 -0700
+++ myFirstExp.cpp 2012-04-04 20:30:05.499767001 -0700
@@ -1,6 +1,7 @@
#include <iostream>
#include <stdio.h>
#include <signal.h>
+#include <strings.h>
#define UNW_LOCAL_ONLY
#include <libunwind.h>
@@ -11,7 +12,7 @@
unw_word_t temp_ip, temp_sp;
ucontext_t* temp_a_uc = (ucontext_t*) a_uc;
unw_init_local(&temp_cursor, temp_a_uc);
- unw_set_reg(&temp_cursor, UNW_REG_IP, 1);
+ //unw_set_reg(&temp_cursor, UNW_REG_IP, 1);
std::cout << "\nStack Trace -----> \n";
while (unw_step(&temp_cursor) > 0) {
unw_get_reg(&temp_cursor, UNW_REG_IP, &temp_ip);
@@ -23,6 +24,7 @@
printf ("temp_ip = %lx, temp_sp = %lx, procedure--> %s\n",
(long) temp_ip, (long) temp_sp, buffer);
}
std::cout << "\n\n";
+ fflush(stdout);
}
void
@@ -71,7 +73,8 @@
int
main(){
struct sigaction new_sigaction, old_sigaction;
-
+
+ bzero(&new_sigaction, sizeof(struct sigaction));
new_sigaction.sa_sigaction = segv_handler;
new_sigaction.sa_flags = SA_SIGINFO;
@@ -79,7 +82,7 @@
sigaddset(&new_sigaction.sa_mask, SIGSEGV);
- sigaction (SIGSEGV, NULL, &new_sigaction);
+ sigaction (SIGSEGV, &new_sigaction, NULL);
if (old_sigaction.sa_handler != SIG_IGN){
new_sigaction.sa_handler = test_signal_handler;
Also needed this fix to libunwind:
x86_64: continue unwinding frame chain.
dwarf_get() returns zero on success. However a return value of 0 from
unw_step() causes unwinding to stop.
--- a/src/x86_64/Gstep.c
+++ b/src/x86_64/Gstep.c
@@ -206,6 +206,7 @@ unw_step (unw_cursor_t *cursor)
Debug (2, "returning %d\n", ret);
return ret;
}
+ ret = 1;
}
else
c->dwarf.ip = 0;
If you want all of this to work without -fno-omit-frame-pointer,
things become a bit more complicated. We'll somehow have to
(heuristically?) unwind up to the point where IP is valid. libunwind
knows what to do after that.
-Arun