Re: Getting call stack (like dbx where cmd) Shaun Clowes wrote:
> "Adrian" <notvalid@null.net> wrote in message
> news:10o52t92hdgik76@news.supernews.com...
>
>>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
>
>
thanks Shaun for the code fragment. I'm using it in conjuction
with the GNU "bfd" library to do what I want. If anyone else
is interested, you can use the code fragment above with code
fragments from GNU binutils as a solution (look at say,
addr2line.c)
I'm sure there is a more streamlined way to do this but this is
a good starting point.
adrian |