Adrian said:
I am working with IBM compiler and AIX but any other
OS/compiler solution would be interesting as well.
Well, since this completely OS/Architecture specific you'll generally have
to search newsgroups for solutions for the specific platforms you're looking
for. Anyways, for AIX it'll look something like this:
void FaultHandler(int iSignal, siginfo_t *ptSigInfo, void *pvSomething)
{
DumpCallStack(1, (ucontext_t *) pvSomething);
}
void DumpCallStack(int iFd, ucontext_t *ptContext)
void *pvInstructionPointer;
void **ppvStackFrame;
int iFrame = 0;
/* The standard stack layout for a process on the PowerPC architecture
(AIX ABI) when a() has called b() which called c() looks
like the following:
--------------------------------
-- | Saved Stack Pointer | <-- Stack pointer (%R1/SP)
| | Saved Control Register |
| | Saved Location Register | Not used until call out of
C()
| --------------------------------
| | |
| | Local Variables for c() |
| | |
| --------------------------------
-> | Saved Stack Pointer | --
| Saved Control Register | |
| Saved Location Register | | Saved by c() containing
location
-------------------------------- | or call from b()
| | |
| Local Variables for b() | |
| | |
-------------------------------- |
| Saved Stack Pointer | <-
| Saved Control Register |
| Saved Location Register | Saved by b() containing
location
-------------------------------- or call from a()
| |
| Local Variables for a() |
| |
--------------------------------
Refer to the PowerPC Compiler Writer's Guide or the AIX Assembly
Language
Reference for more information */
sprintf(sString, "Faulted while executing instruction at 0x%08x\n"
"\n"
"Traceback:\n",
ptContext->uc_mcontext.jmp_context.iar);
write(iFd, sString, strlen(sString));
/* Roll down the stack frames */
pvInstructionPointer = (void *) ptContext->uc_mcontext.jmp_context.iar;
ppvStackFrame = (void **) ptContext->uc_mcontext.jmp_context.gpr[1];
do
{
sprintf(sString, "(%2d) 0x%p\n", iFrame, pvInstructionPointer);
write(iFd, sString, strlen(sString));
/* Have we hit the bottom of the stack? */
if (!ppvStackFrame[0])
break;
/* Validate the stack frame before using any portion of it */
if (!ValidAddress((void *) ppvStackFrame) ||
!ValidAddress((void *) ppvStackFrame[0]) ||
!ValidAddress((void *) ((void **) ppvStackFrame[0] + 2)))
{
sprintf(sString, "Invalid frame at %p\n", (void *) ppvStackFrame);
write(iFd, sString, strlen(sString));
break;
}
ppvStackFrame = (void **) ppvStackFrame[0];
pvInstructionPointer = ppvStackFrame[2];
iFrame++;
} while(ppvStackFrame);
Cheers,
Shaun