CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
156 lines
6.9 KiB
TeX
156 lines
6.9 KiB
TeX
\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.}
|