[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Frame Information (Backtrace)
From: |
Chris B. Vetter |
Subject: |
Re: Frame Information (Backtrace) |
Date: |
Thu, 15 Jan 2004 10:11:55 -0800 |
On Thu, 15 Jan 2004 15:38:05 +0100
Philip Mötteli <Philip.Moetteli@tele2.ch> wrote:
> I try to implement a debugging help for "double free". In order to do
> that, I would like to save something like a backtrace. I know, how to
> get the address of the frame (NSFrameAddress()), but what type does
> this "void*" return value has? How can I filter the SEL out of it?
// may be compiler and arch dependant
#define FRAME_RETURN_OFFSET 4
#define FRAME_ARG_OFFSET 8
#define FRAME_RETURN_ADDRESS(fp) \
(*(void**)((char *)(fp) + FRAME_RETURN_OFFSET))
#define FRAME_ARG_START(fp) \
((void*)((char *)(fp) + FRAME_ARG_OFFSET))
#define marg_get_ref(mArgs, anOffset, aType) \
( (aType *)((char *) mArgs + anOffset) )
#define marg_get_value(mArgs, anOffset, aType) \
( *marg_get_ref(mArgs, anOffset, aType) )
void dumpBacktrace(unsigned int startFrameNumber)
{
unsigned int *returnAddress = 0, *framePointer;
unsigned int *argStart;
SEL sel;
framePointer = NSFrameAddress(startFrameNumber);
if( NULL == framePointer ) return;
returnAddress = FRAME_RETURN_ADDRESS(framePointer);
argStart = FRAME_ARG_START(framePointer);
sel = marg_getValue(argStart, _cmdOffset, SEL);
if( sel && sel_is_mapped(sel) )
// sel is valid, ie. a method not a function
else
// it's a function
return;
}
No error checking. If 'sel' isn't mapped, you'll probably get a core
dump, plus you would probably want to loop through the frames, eg.
#define MAX_FRAMES 50 // # of frames to dump
#define FRAME_NEXT_OFFSET 0 // depending on arch/compiler
#define NEXT_FRAME(fp) \
(*(void**)((char *)(fp) + FRAME_NEXT_OFFSET))
while( frameCount < MAX_FRAMES
&& (framePointer = NEXT_FRAME(framePointer)) )
{
argStart = FRAME_ARG_START(framePointer);
[... as above...]
++frameCount;
returnAddress = FRAME_RETURN_ADDRESS(framePointer);
}
return;
I use something like this in a signal handler that dumps a stack
backtrace upon receiving a 'terminate' signal.
--
Chris