discuss-gnustep
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]