* Signal backtrace function
@ 2008-04-09 18:16 Joakim Tjernlund
2008-04-14 16:09 ` Detlev Zundel
0 siblings, 1 reply; 4+ messages in thread
From: Joakim Tjernlund @ 2008-04-09 18:16 UTC (permalink / raw)
To: 'linuxppc-dev Development'
Hi
I made my own backtrace function for printing
a trace from within a signal handler. Maybe it
can be useful for the kernel too? General
comments welcome.
Jocke
#include <stdio.h>
#include <signal.h>
#include <execinfo.h>
#include <unistd.h>
#define __USE_GNU
#include <ucontext.h>
/* This is the stack layout we see with every stack frame.
Note that every routine is required by the ABI to lay out the stack
like this.
+----------------+ +-----------------+
%r1 -> | %r1 last frame--------> | %r1 last frame--->... --> NULL
| | | |
| (unused) | | return address |
+----------------+ +-----------------+
*/
/* Prints a backtrace when invoked from a signal handler */
int
sigbacktrace (void **array, int size, void *sp,
void *lr, void *exec_addr)
{
int count=1, loop;
void *ret_addr;
struct layout {
struct layout * next;
void * return_address;
} *current;
if (!size)
return size;
current = sp;
array[0] = exec_addr;
for (loop = 0;
current != NULL && count < size;
current = current->next, loop++) {
ret_addr = current->return_address;
#if DEBUG
printf("next:%p, ret:%p, LR:%p\n", current->next, ret_addr, lr);
#endif
if (lr == ret_addr) /* false frame ? */
continue;
if (!loop)
if (lr != ret_addr) /* Leaf function ? */
ret_addr = lr;
else
continue;
array[count++] = ret_addr;
}
/* It's possible the second-last stack frame can't return in which
case the CRT startup code will have set its LR to 'NULL'. */
if (count > 0 && array[count-1] == NULL)
count--;
return count;
}
#define EXEC_ADDR (*regs)[32]
#define STK_PTR (*regs)[1]
#define LINK (*regs)[36]
void bt_sighandler(int sig, siginfo_t *info,
void *secret)
{
void *trace[16];
char **messages = (char **)NULL;
int i, trace_size = 0;
ucontext_t *uc = (ucontext_t *)secret;
gregset_t *regs = &uc->uc_mcontext.uc_regs->gregs;
/* Do something useful with siginfo_t */
if (sig == SIGSEGV || sig == SIGBUS)
printf("Got signal %d, faulty address is %p, "
"from %p\n", sig, info->si_addr,
EXEC_ADDR);
else
printf("Got signal %d\n", sig);
trace_size = sigbacktrace(trace, 16, (void*) STK_PTR,
(void*) LINK, (void*) EXEC_ADDR);
messages = backtrace_symbols(trace, trace_size);
printf("[bt] Execution path:\n");
for (i=0; i<trace_size; ++i)
printf("[bt] %s\n", messages[i]);
if (sig != SIGUSR1)
exit(0);
}
void dummy(void)
{
unsigned long *current;
asm volatile ("" : "=l"(current));
}
int func_a(int a, char b) {
char *p = (char *)0xdeadbeef;
//dummy(); /* Test with and without this call */
a = a + b;
*p = 10; /* CRASH here!! */
dummy(); /* Test with and without this call */
return 2*a;
}
int func_b() {
int res, a = 5;
res = 5 + func_a(a, 't');
return res;
}
int main() {
/* Install our signal handler */
struct sigaction sa;
sa.sa_sigaction = (void *)bt_sighandler;
sigemptyset (&sa.sa_mask);
sa.sa_flags = SA_RESTART | SA_SIGINFO;
sigaction(SIGSEGV, &sa, NULL);
sigaction(SIGBUS, &sa, NULL);
sigaction(SIGUSR1, &sa, NULL);
/* ... add any other signal here */
/* Do something */
printf("%d\n", func_b());
}
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Signal backtrace function
2008-04-09 18:16 Signal backtrace function Joakim Tjernlund
@ 2008-04-14 16:09 ` Detlev Zundel
2008-04-14 16:20 ` Joakim Tjernlund
0 siblings, 1 reply; 4+ messages in thread
From: Detlev Zundel @ 2008-04-14 16:09 UTC (permalink / raw)
To: linuxppc-dev
Hi Jocke,
> I made my own backtrace function for printing
> a trace from within a signal handler. Maybe it
> can be useful for the kernel too? General
> comments welcome.
Probably a dumb question, but doesn't backtrace(3) from glibc work
architecture independent already? Why do you need to reimplement it?
Thanks
Detlev
--
The management question ... is not _whether_ to build a pilot system
and throw it away. You _will_ do that. The only question is whether to
plan in advance to build a throwaway, or to promise to deliver the
throwaway to customers. - Fred Brooks, "The Mythical Man Month"
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-40 Fax: (+49)-8142-66989-80 Email: dzu@denx.de
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Signal backtrace function
2008-04-14 16:09 ` Detlev Zundel
@ 2008-04-14 16:20 ` Joakim Tjernlund
2008-04-15 15:50 ` Detlev Zundel
0 siblings, 1 reply; 4+ messages in thread
From: Joakim Tjernlund @ 2008-04-14 16:20 UTC (permalink / raw)
To: Detlev Zundel; +Cc: linuxppc-dev
On Mon, 2008-04-14 at 18:09 +0200, Detlev Zundel wrote:
> Hi Jocke,
>
> > I made my own backtrace function for printing
> > a trace from within a signal handler. Maybe it
> > can be useful for the kernel too? General
> > comments welcome.
>
> Probably a dumb question, but doesn't backtrace(3) from glibc work
> architecture independent already? Why do you need to reimplement it?
Nope, it doesn't give you a good backtrace from within a signal handler.
On x86 you can use the normal backtrace function with a minor
workaround, but as ppc doesn't save a FP in leaf functions, that
workaround does not work well. You can read more about it
at http://www.linuxjournal.com/article/6391
Jocke
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Signal backtrace function
2008-04-14 16:20 ` Joakim Tjernlund
@ 2008-04-15 15:50 ` Detlev Zundel
0 siblings, 0 replies; 4+ messages in thread
From: Detlev Zundel @ 2008-04-15 15:50 UTC (permalink / raw)
To: joakim.tjernlund; +Cc: linuxppc-dev
Hi Jocke,
> On Mon, 2008-04-14 at 18:09 +0200, Detlev Zundel wrote:
>> Hi Jocke,
>>
>> > I made my own backtrace function for printing
>> > a trace from within a signal handler. Maybe it
>> > can be useful for the kernel too? General
>> > comments welcome.
>>
>> Probably a dumb question, but doesn't backtrace(3) from glibc work
>> architecture independent already? Why do you need to reimplement it?
>
> Nope, it doesn't give you a good backtrace from within a signal handler.
> On x86 you can use the normal backtrace function with a minor
> workaround, but as ppc doesn't save a FP in leaf functions, that
> workaround does not work well. You can read more about it
> at http://www.linuxjournal.com/article/6391
Thanks for clearing that up. I wasn't aware of that limitation.
Cheers
Detlev
--
In short: much of our country's [USA] counterterrorism security spending is
not designed to protect us from the terrorists, but instead to protect our
public officials from criticism when another attack occurs.
-- Bruce Schneier
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-40 Fax: (+49)-8142-66989-80 Email: dzu@denx.de
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2008-04-15 15:51 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-04-09 18:16 Signal backtrace function Joakim Tjernlund
2008-04-14 16:09 ` Detlev Zundel
2008-04-14 16:20 ` Joakim Tjernlund
2008-04-15 15:50 ` Detlev Zundel
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).