-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf Of Arun
Sharma
Sent: Sunday, March 25, 2012 9:53 PM
To: Prabhat Verma
Cc: [email protected]
Subject: Re: [Libunwind-devel] Libunwind support for NULL IP
On Fri, Mar 16, 2012 at 8:55 AM, Prabhat Verma <[email protected]>
wrote:
> We are trying to replace backtrace with libunwind (local unwinding)
> for our diagnostic purposes. A major motivation behind this decision
> was the inability of backtrace to handle stack frames containing NULL
> IP. In our case, this may happen if someone ends up doing this:
>>I pushed a few changes to the git repo. Could you please try them to see if
>>things work better for you?
>>In short: dwarf says NULL RBP is the end of the callchain. But libunwind was
>>terminating unwind on NULL RIP as well.
>>In the process I seem to have introduced a test failure (run-ptrace-misc used
>>to pass earlier). I'll dig into it when I get a chance. On the face of it, it
>>looks like unwinding from (ip == 0) used to succeed earlier, but it fails now
>>(due to lack of unwind info?).
>>-Arun
I tried this fix but it seems to be broken in more ways than expected...
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.
-Prabhat
#include <iostream>
#include <stdio.h>
#include <signal.h>
#define UNW_LOCAL_ONLY
#include <libunwind.h>
void
my_unw_step_and_print_stack_native(void * a_uc) {
unw_cursor_t temp_cursor;
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);
std::cout << "\nStack Trace -----> \n";
while (unw_step(&temp_cursor) > 0) {
unw_get_reg(&temp_cursor, UNW_REG_IP, &temp_ip);
unw_get_reg(&temp_cursor, UNW_REG_SP, &temp_sp);
char buffer[100];
unw_word_t offset, *poffset;
poffset = &offset;
unw_get_proc_name(&temp_cursor, (char *)buffer, 99, poffset);
printf ("temp_ip = %lx, temp_sp = %lx, procedure--> %s\n", (long)
temp_ip, (long) temp_sp, buffer);
}
std::cout << "\n\n";
}
void
bail(){
std::cout << "\nInside bail ()\n";
void (*fp)() = NULL;
fp();
}
void foo () {
std::cout << "\nInside foo ()\n";
bail();
}
void foo1() { std::cout << "\nInside foo1()"; foo (); }
void foo2() { std::cout << "\nInside foo2()"; foo1(); }
void foo3() { std::cout << "\nInside foo3()"; foo2(); }
void foo4() { std::cout << "\nInside foo4()"; foo3(); }
void foo5() { std::cout << "\nInside foo5()"; foo4(); }
void foo6() { std::cout << "\nInside foo6()"; foo5(); }
void foo7() { std::cout << "\nInside foo7()"; foo6(); }
void foo8() { std::cout << "\nInside foo8()"; foo7(); }
void foo9() { std::cout << "\nInside foo9()"; foo8(); }
void
segv_handler (int signum, siginfo_t* info, void *old_context){
std::cout << "\nInside segv_handler\n";
//Let OS supply context
my_unw_step_and_print_stack_native(old_context);
std::cout << "\n\nBAILING...\n\n";
//Bail on SIGSEGV default bahavior
signal(SIGSEGV, SIG_DFL);
}
void
test_signal_handler(int signum){
std::cout << "\nInside test_signal_handler. I should not be here...\n";
//Bail on SIGSEGV (default behavior)
signal(SIGSEGV, SIG_DFL);
}
int
main(){
struct sigaction new_sigaction, old_sigaction;
new_sigaction.sa_sigaction = segv_handler;
new_sigaction.sa_flags = SA_SIGINFO;
sigemptyset (&new_sigaction.sa_mask);
sigaddset(&new_sigaction.sa_mask, SIGSEGV);
sigaction (SIGSEGV, NULL, &new_sigaction);
if (old_sigaction.sa_handler != SIG_IGN){
new_sigaction.sa_handler = test_signal_handler;
new_sigaction.sa_sigaction = segv_handler;
sigaction (SIGSEGV, &new_sigaction, &old_sigaction);
}
foo9();
return 0;
}
_______________________________________________
Libunwind-devel mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/libunwind-devel