\subsubsection{Class FrameStepper}\label{subsec:framestepper}
\definedin{framestepper.h}
	
The \code{FrameStepper} class is an interface that tells StackwalkerAPI how to walk
through a specific type of stack frame. There may be many different ways of
walking through a stack frame on a platform, e.g, on Linux/x86 there are
different mechanisms for walking through system calls, signal handlers, regular
functions, and frameless functions. A single \code{FrameStepper} describes how to walk
through one of these types of stack frames.

A user can create their own \code{FrameStepper} classes that tell StackwalkerAPI how to
walk through new types of stack frames. A new \code{FrameStepper} object must be added
to a \code{StepperGroup} before it can be used. 

In addition to walking through individual stack frames, a \code{FrameStepper} tells its
\code{StepperGroup} when it can be used. The \code{FrameStepper} registers address ranges that
cover objects in the target process' code space (such as functions). These
address ranges should contain the objects that will create stack frames through
which the \code{FrameStepper} can walk. If multiple \code{FrameStepper} objects have
overlapping address ranges, then a priority value is used to determine which
\code{FrameStepper} should be attempted first.

\code{FrameStepper} is an interface class; it cannot be instantiated. Users who want to
develop new \code{FrameStepper} objects should inherit from this class and implement
the the desired virtual functions. The \code{getCallerFrame,
  getPriority}, and \code{getName} functions must be implemented; all
others may be overridden if desired. 

\begin{apient}
typedef enum { 
    gcf_success,
    gcf_stackbottom,
    gcf_not_me, 
    gcf_error 
} gcframe_ret_t
\end{apient}

\begin{apient}
virtual gcframe_ret_t getCallerFrame(const Frame &in, Frame &out) = 0
\end{apient}
\apidesc{
This method walks through a single stack frame and generates a Frame object that
represents the caller's stack frame. Parameter in will be a Frame object that
this FrameStepper is capable of walking through. Parameter out is an output
parameter that this method should set to the Frame object that called in.

There may be multiple ways of walking through a different types of stack frames.
Each \code{FrameStepper} class should be able to walk through a type of stack frame.
For example, on x86 one \code{FrameStepper} could be used to walk through stack frames
generated by ABI-compliant functions; out's FP and RA are found by reading from
in's FP, and out's SP is set to the word below in's FP. A different \code{FrameStepper}
might be used to walk through stack frames created by functions that have
optimized away their FP. In this case, in may have a FP that does not point
out's FP and RA. The \code{FrameStepper} will need to use other mechanisms to discover
out's FP or RA; perhaps the \code{FrameStepper} searches through the stack for the RA
or performs analysis on the function that created the stack frame.

If \code{getCallerFrame} successfully walks through in, it is required to set the
following parameters in out. See Section~\ref{subsec:frame} for more details on the values
that can be set in a Frame object:

\begin{description}
    \item [Return Address (RA)] The RA should be set with the
        \code{Frame::setRA} method.
    \item [Stack Pointer (SP)] The SP should be set with the \code{Frame::setSP} method.
    \item [Frame Pointer (FP)] The FP should be set with the \code{Frame::setFP} method
\end{description}

Optionally, getCallerFrame can also set any of following parameters in out:
\begin{description}
    \item [Return Address Location (RALocation)] The RALocation should be set
        with the \code{Frame::setRALocation()} method.
    \item [Stack Pointer Location (SPLocation)] The SPLocation should be set
        with the \code{Frame::setRALocation()} method.
    \item [Frame Pointer Location (FPLocation)] The FPLocation should be set
        with the \code{Frame::setFPLocation()} method.
\end{description}

If a location field in out is not set, then the appropriate
\code{Frame::getRALocation}, \code{Frame::getSPLocation} or
\code{Frame::getFPLocation} method will
return \code{loc\_unknown}.

\code{getCallerFrame} should return \code{gcf\_success} if it successfully walks
through in and creates an \code{out} \code{Frame} object. It should return
\code{gcf\_stackbottom} if in is the bottom of the stack and there are no stack
frames below it. It should return \code{gcf\_not\_me} if in is not the correct
type of stack frame for this \code{FrameStepper} to walk through. StackwalkerAPI
will then attempt to locate another \code{FrameStepper} to handle \code{in} or
abort the stackwalk. It should return \code{gcf\_error} if there was an error
and the stack walk should be aborted.
}

\begin{apient}
virtual void registerStepperGroup(StepperGroup *steppergroup)
\end{apient}
\apidesc{
This method is used to notify a \code{FrameStepper} when StackwalkerAPI adds it to a
\code{StepperGroup}. The \code{StepperGroup} to which this \code{FrameStepper} is being added is
passed in parameter steppergroup. This method can be used to initialize the
\code{FrameStepper} (in addition to any \code{FrameStepper} constructor).
}

\begin{apient}
virtual unsigned getPriority() const = 0
\end{apient}
\apidesc{
This method is used by the \code{StepperGroup} to decide which \code{FrameStepper} to use if
multiple \code{FrameStepper} objects are registered over the same address range (see
addAddressRanges in Section~\ref{subsec:steppergroup} for more information about address ranges).
This method returns an integer representing a priority level, the lower the
number the higher the priority.

The default \code{FrameStepper} objects provided by StackwalkerAPI all return
priorities between \code{0x1000} and \code{0x2000}. If two \code{FrameStepper} objects have an
overlapping address range, and they have the same priority, then the order in
which they are used is undefined.
}

\begin{apient}
FrameStepper(Walker *w);
\end{apient}
\apidesc{Constructor definition for all \code{FrameStepper}
  instances.}

\begin{apient}
virtual ProcessState *getProcessState();
\end{apient}
\apidesc{Return the \code{ProcessState} used by the
  \code{FrameStepper}. Can be overridden if the user desires.}

\begin{apient}
virtual Walker *getWalker();
\end{apient}

\apidesc{Return the \code{Walker} associated with the
  \code{FrameStepper}. Can be overridden if the user desires.}

\begin{apient}
typedef std::pair<std::string, Address> LibAddrPair;
typedef enum { library_load, library_unload } lib_change_t;
virtual void newLibraryNotification(LibAddrPair *libAddr, 
                                    lib_change_t change);
\end{apient}

\apidesc{This function is called when a new library is loaded by the
process; it should be implemented if the \code{FrameStepper} requires
such information.}

\begin{apient}
virtual const char *getName() const = 0;
\end{apient}

\apidesc{Returns a name for the \code{FrameStepper}; must be
  implemented by the user.}
