\section{Introduction}
\label{sec:intro}
This document describes StackwalkerAPI, an API and library for walking a call
stack. The call stack (also known as the run-time stack) is a stack found in a
process that contains the currently active stack frames. Each stack frame is a
record of an executing function (or function-like object such as a signal
handler or system call). StackwalkerAPI provides an API that allows users to
collect a call stack (known as walking the call stack) and access information
about its stack frames. The current implementation supports Linux/x86,
Linux/x86-64, Linux/Power, Linux/Power-64, Windows/x86, BlueGene/L, and BlueGene/P.

StackwalkerAPI is designed to be both easy-to-use and easy-to-extend. Users can
easily use StackwalkerAPI to walk a call stack without needing to understand how
call stacks are laid out on their platform. Users can easily extend
StackwalkerAPI to work with new platforms and types of stack frames by
implementing a set of callbacks that can be plugged into StackwalkerAPI.

StackwalkerAPI's ease-of-use comes from it providing a platform independent
interface that allows users to access detailed information about the call stack.
For example, the following C++ code-snippet is all that is needed to walk and
print the call stack of the currently running thread.

\lstset{language=[GNU]C++,basicstyle=\ttfamily\selectfont\small}
\lstset{numbers=none}
\begin{lstlisting}
std::vector<Frame> stackwalk; 
string s;

Walker *walker = Walker::newWalker();
walker->walkStack(stackwalk);
for (unsigned i=0; i<stackwalk.size(); i++) {
		stackwalk[i].getName(s);
		cout << "Found function " << s << endl;
}	
\end{lstlisting}

StackwalkerAPI can walk a call stack in the same address space as where the
StackwalkerAPI library lives (known as a first party stackwalk), or it can walk
a call stack in another process (known as a third party stackwalk). To change
the above example to perform a third party stackwalk, we would only need to pass
a process identifier to newWalker, e.g: 
\begin{lstlisting}
Walker *walker = Walker::newWalker(pid);
\end{lstlisting}
	
Our other design goal with StackwalkerAPI is to make it easy-to-extend. The
mechanics of how to walk through a stack frame can vary between different
platforms, and even between different types of stack frames on the same
platform. In addition, different platforms may have different mechanisms for
reading the data in a call stack or looking up symbolic names that go with a
stack frame. StackwalkerAPI provides a callback interface for plugging in
mechanisms for handling new systems and types of stack frames. The callback
interface can be used to port StackwalkerAPI to new platforms, extend
StackwalkerAPI support on existing systems, or more easily integrate
StackwalkerAPI into existing tools. There are callbacks for the following
StackwalkerAPI operations:

\begin{description}
    \item[Walk through a stack frame] StackwalkerAPI will find different types
        of stack frames on different platforms and even within the same
        platform. For example, on Linux/x86 the stack frame generated by a
        typical function looks different from the stack frame generated by a
        signal handler. The callback interface can be used to register a handler
        with StackwalkerAPI that knows how to walk through a new type of stack
        frame. For example, the DyninstAPI tool registers an object with
        StackwalkerAPI that describes how to walk through the stack frames
        generated by its instrumentation.
    
    \item[Access process data] To walk a call stack, StackwalkerAPI needs to be
        able to read a process' memory and registers. When doing a first party
        stackwalk, this is done by directly reading them from the current
        address space. When doing a third party stackwalk, this is done by
        reading them using a debugger interface. The callback interface can be
        used to register new objects for accessing process data. This can be
        used, for example, to port StackwalkerAPI to a new operating system or
        make it work with a new debugger interface.
    
    \item[Look up symbolic names] When StackwalkerAPI finds a stack frame, it
        gets an address that points into the piece of code that created that
        stack frame. This address is not necessarily meaningful to a user, so
        StackwalkerAPI attempts to associate the address with a symbolic name.
        The callback interface can be used to register an object with
        StackwalkerAPI that performs an address to name mapping, allowing
        StackwalkerAPI to associate names with stack frames.  
\end{description}
