diff --git a/docs/index.rst b/docs/index.rst
index 925a3c0a37..3ecc955bc0 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -38,6 +38,9 @@ to more effectively use different aspects of binary analysis for building their
:ref:`sec:proccontrolapi-intro`
An API and library for controlling processes
+:ref:`sec:stackwalk-intro`
+ Collect and analyze stack traces
+
.. _main-support:
-------
@@ -90,6 +93,7 @@ Developed by
parseAPI/overview
patchAPI/overview
proccontrol/overview
+ stackwalk/overview
usertools/DynC/overview
.. toctree::
@@ -116,6 +120,7 @@ Developed by
parseAPI/public/API
patchAPI/public/API
proccontrol/public/API
+ stackwalk/public/API
.. toctree::
:caption: developer docs
@@ -128,6 +133,7 @@ Developed by
parseAPI/developer/API
patchAPI/developer/API
proccontrol/developer/API
+ stackwalk/developer/API
.. toctree::
:caption: advanced
diff --git a/docs/stackwalk/developer/API.rst b/docs/stackwalk/developer/API.rst
new file mode 100644
index 0000000000..38c9bf9fa9
--- /dev/null
+++ b/docs/stackwalk/developer/API.rst
@@ -0,0 +1,22 @@
+============
+StackwalkAPI
+============
+
+.. toctree::
+ :caption: Developer API
+ :name: stackwalk-developer-api
+ :hidden:
+ :maxdepth: 1
+
+ aarch64-swk.h
+ analysis_stepper.h
+ dbgstepper-impl.h
+ framestepper_pimple.h
+ freebsd-swk.h
+ get_trap_instruction.h
+ libstate.h
+ linuxbsd-swk.h
+ linux-swk.h
+ sw.h
+ symtab-swk.h
+ x86-swk.h
\ No newline at end of file
diff --git a/docs/stackwalk/developer/aarch64-swk.h.rst b/docs/stackwalk/developer/aarch64-swk.h.rst
new file mode 100644
index 0000000000..f63e7595c4
--- /dev/null
+++ b/docs/stackwalk/developer/aarch64-swk.h.rst
@@ -0,0 +1,5 @@
+aarch64-swk.h
+=============
+
+.. cpp:namespace:: Dyninst::stackwalk
+
diff --git a/docs/stackwalk/developer/analysis_stepper.h.rst b/docs/stackwalk/developer/analysis_stepper.h.rst
new file mode 100644
index 0000000000..68013cdc62
--- /dev/null
+++ b/docs/stackwalk/developer/analysis_stepper.h.rst
@@ -0,0 +1,5 @@
+analysis_stepper.h
+==================
+
+.. cpp:namespace:: Dyninst::stackwalk
+
diff --git a/docs/stackwalk/developer/dbgstepper-impl.h.rst b/docs/stackwalk/developer/dbgstepper-impl.h.rst
new file mode 100644
index 0000000000..00bf0be034
--- /dev/null
+++ b/docs/stackwalk/developer/dbgstepper-impl.h.rst
@@ -0,0 +1,5 @@
+dbgstepper-impl.h
+=================
+
+.. cpp:namespace:: Dyninst::stackwalk
+
diff --git a/docs/stackwalk/developer/framestepper_pimple.h.rst b/docs/stackwalk/developer/framestepper_pimple.h.rst
new file mode 100644
index 0000000000..65d7a2cbb8
--- /dev/null
+++ b/docs/stackwalk/developer/framestepper_pimple.h.rst
@@ -0,0 +1,5 @@
+framestepper_pimple.h
+=====================
+
+.. cpp:namespace:: Dyninst::stackwalk
+
diff --git a/docs/stackwalk/developer/freebsd-swk.h.rst b/docs/stackwalk/developer/freebsd-swk.h.rst
new file mode 100644
index 0000000000..335ebf9a63
--- /dev/null
+++ b/docs/stackwalk/developer/freebsd-swk.h.rst
@@ -0,0 +1,5 @@
+freebsd-swk.h
+=============
+
+.. cpp:namespace:: Dyninst::stackwalk
+
diff --git a/docs/stackwalk/developer/get_trap_instruction.h.rst b/docs/stackwalk/developer/get_trap_instruction.h.rst
new file mode 100644
index 0000000000..fe5d3c55aa
--- /dev/null
+++ b/docs/stackwalk/developer/get_trap_instruction.h.rst
@@ -0,0 +1,5 @@
+get_trap_instruction.h
+======================
+
+.. cpp:namespace:: Dyninst::stackwalk
+
diff --git a/docs/stackwalk/developer/libstate.h.rst b/docs/stackwalk/developer/libstate.h.rst
new file mode 100644
index 0000000000..e1ae9361a7
--- /dev/null
+++ b/docs/stackwalk/developer/libstate.h.rst
@@ -0,0 +1,5 @@
+libstate.h
+==========
+
+.. cpp:namespace:: Dyninst::stackwalk
+
diff --git a/docs/stackwalk/developer/linux-swk.h.rst b/docs/stackwalk/developer/linux-swk.h.rst
new file mode 100644
index 0000000000..d6c24710d7
--- /dev/null
+++ b/docs/stackwalk/developer/linux-swk.h.rst
@@ -0,0 +1,5 @@
+linux-swk.h
+===========
+
+.. cpp:namespace:: Dyninst::stackwalk
+
diff --git a/docs/stackwalk/developer/linuxbsd-swk.h.rst b/docs/stackwalk/developer/linuxbsd-swk.h.rst
new file mode 100644
index 0000000000..ddcc4d7267
--- /dev/null
+++ b/docs/stackwalk/developer/linuxbsd-swk.h.rst
@@ -0,0 +1,5 @@
+linuxbsd-swk.h
+==============
+
+.. cpp:namespace:: Dyninst::stackwalk
+
diff --git a/docs/stackwalk/developer/sw.h.rst b/docs/stackwalk/developer/sw.h.rst
new file mode 100644
index 0000000000..e233291e80
--- /dev/null
+++ b/docs/stackwalk/developer/sw.h.rst
@@ -0,0 +1,5 @@
+sw.h
+====
+
+.. cpp:namespace:: Dyninst::stackwalk
+
diff --git a/docs/stackwalk/developer/symtab-swk.h.rst b/docs/stackwalk/developer/symtab-swk.h.rst
new file mode 100644
index 0000000000..7fa54f7ab3
--- /dev/null
+++ b/docs/stackwalk/developer/symtab-swk.h.rst
@@ -0,0 +1,5 @@
+symtab-swk.h
+============
+
+.. cpp:namespace:: Dyninst::stackwalk
+
diff --git a/docs/stackwalk/developer/x86-swk.h.rst b/docs/stackwalk/developer/x86-swk.h.rst
new file mode 100644
index 0000000000..da7e2492cb
--- /dev/null
+++ b/docs/stackwalk/developer/x86-swk.h.rst
@@ -0,0 +1,5 @@
+x86-swk.h
+=========
+
+.. cpp:namespace:: Dyninst::stackwalk
+
diff --git a/docs/stackwalk/index.rst b/docs/stackwalk/overview.rst
similarity index 78%
rename from docs/stackwalk/index.rst
rename to docs/stackwalk/overview.rst
index fd2c4e5daa..687f36f997 100644
--- a/docs/stackwalk/index.rst
+++ b/docs/stackwalk/overview.rst
@@ -1,17 +1,19 @@
.. _`sec:stackwalk-intro`:
-Stackwalk Introduction
-======================
+.. cpp:namespace:: Dyninst::Stackwalker
-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
+===========
+Stackwalker
+===========
+
+Stackwalker is a 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, and Windows/x86.
+implementation supports Linux/x86, Linux/x86-64, Linux/Power-64, and Windows/x86.
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
@@ -20,103 +22,122 @@ 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.
+.. _`sec:stackwalk-abstractions`:
-.. code-block:: cpp
+Abstractions
+============
- std::vector stackwalk;
- string s;
+StackwalkerAPI contains two interfaces: the Stackwalking Interface and
+the Callback Interface. The stackwalking interface is used to walk the
+call stack, query information about stack frames, and collect basic
+information about threads. The Callback Interface is used to provide
+custom mechanisms for walking a call stack. Users who operate in one of
+StackwalkerAPI’s standard configurations do not need to use the Callback
+Interface.
- Walker *walker = Walker::newWalker();
- walker->walkStack(stackwalk);
- for (unsigned i=0; i`__ shows the
-ownership hierarchy for StackwalkerAPI’s classes. Ownership is a
-"contains" relationship; if one class owns another, then instances of
-the owner class maintain an exclusive instance of the other. For
-example, in Figure `[fig:object-ownership] <#fig:object-ownership>`__
-the each Walker instance contains exactly one instance of a ProcessState
-object. No other instance of Walker uses that instance of ProcessState.
+Host Process
+ The process in which StackwalkerAPI code is currently running.
-This remainder of this section briefly describes the six classes that
-make up StackwalkerAPI’s two interfaces. For more details, see the class
-descriptions in Section `3 <#sec:api>`__.
+First Party Stackwalk
+ StackwalkerAPI collects first party stackwalk when it walks a call
+ stack in the same address space it is running in, i.e. the target
+ process is the same as the host process.
-= [rectangle, draw, rounded corners]
+Third Party Stackwalk
+ StackwalkerAPI collects third party stackwalk when it walks the call
+ stack in a different address space from the one it is running in,
+ i.e. the target process is different from the host process. A third
+ party stackwalk is usually done through a debugger interface.
Stackwalking Interface
----------------------
@@ -182,123 +203,148 @@ SymbolLookup
StackwalkerAPI. A user could, for example, use this interface to
allow StackwalkerAPI to use libelf to look up symbol names instead.
-.. _`sec:stackwalk-api`:
-
-Stackwalk API Reference
-=======================
-This section describes the StackwalkerAPI interface. It is divided into
-three sub-sections: a description of the definitions and basic types
-used by this API, a description of the interface for collecting
-stackwalks, and a description of the callback interface.
-Definitions and Basic Types
----------------------------
-
-The following definitions and basic types are referenced throughout the
-rest of this manual.
+Callback Interface Default Implementations
+==========================================
-.. _`subsec:definitions`:
+StackwalkerAPI provides one or more default implementations of each of
+the callback classes. These implementations are used by a default configuration of StackwalkerAPI.
-Definitions
-~~~~~~~~~~~
+.. _`subsec:debugger`:
-Stack Frame
- A stack frame is a record of a function (or function-like object)
- invocation. When a function is executed, it may create a frame on the
- call stack. StackwalkerAPI finds stack frames and returns a
- description of them when it walks a call stack. The following three
- definitions deal with stack frames.
+Debugger Interface
+------------------
-Bottom of the Stack
- The bottom of the stack is the earliest stack frame in a call stack,
- usually a thread’s initial function. The stack grows from bottom to
- the top.
+This section describes how to use StackwalkerAPI for collecting 3rd
+party stack walks. In 3rd party mode StackwalkerAPI uses the OS’s
+debugger interface to connect to another process and walk its call
+stacks. As part of being a debugger StackwalkerAPI receives and needs to
+handle debug events. When a debugger event occurs, StackwalkerAPI must
+get control of the host process in order to receive the debugger event
+and continue the target process.
-Top of the Stack
- The top of the stack is the most recent stack frame in a call stack.
- The stack frame at the top of the stack is for the currently
- executing function.
+To illustrate the complexities with running in 3rd party mode, consider
+the follow code snippet that uses StackwalkerAPI to collect a stack walk
+every five seconds.
-Frame Object
- A Frame object is StackwalkerAPI’s representation of a stack frame. A
- Frame object is a snapshot of a stack frame at a specific point in
- time. Even if a stack frame changes as a process executes, a Frame
- object will remain the same. Each Frame object is represented by an
- instance of the Frame class.
+.. code-block:: cpp
+
+ Walker *walker = Walker::newWalker(pid);
+ std::vector swalk;
+ for (;;) {
+ walker->walkStack(swalk);
+ sleep(5);
+ }
-The following three definitions deal with fields in a Frame object.
+StackwalkerAPI is running in 3rd party mode, since it attached to the
+target process, ``pid``. As the target process runs it may be generating
+debug events such a thread creation and destruction, library loads and
+unloads, signals, forking/execing, etc. When one of these debugger
+events is generated the OS will pause the target process and send a
+notice to the host process. The target process will remain paused until
+the host process handles the debug event and resumes the target process.
-SP (Stack Pointer)
- A Frame object’s SP member points to the top of its stack frame (a
- stack frame grows from bottom to top, similar to a call stack). The
- Frame object for the top of the stack has a SP that is equal to the
- value in the stack pointer register at the time the Frame object was
- created. The Frame object for any other stack frame has a SP that is
- equal to the top address in the stack frame.
+In the above example the host process is spending almost all of its time
+in the sleep call. If a debugger event happens during the sleep, then
+StackwalkerAPI will not be able to get control of the host process and
+handle the event for up to five seconds. This will cause long pauses in
+the target process and lead to a potentially very large slowdown.
-FP (Frame Pointer)
- A Frame object’s FP member points to the beginning (or bottom) of its
- stack frame. The Frame object for the top of the stack has a FP that
- is equal to the value in the frame pointer register at the time the
- Frame object was created. The Frame object for any other stack frame
- has a FP that is equal to the beginning of the stack frame.
+To work around this problem StackwalkerAPI provides a notification file
+descriptor. This file descriptor represents a connection between the
+StackwalkerAPI library and user code. StackwalkerAPI will write a single
+byte to this file descriptor when a debug event occurs, thus notifying
+the user code that it needs to let StackwalkerAPI receive and handle
+debug events. The user code can use system calls such as select to watch
+for events on the notification file descriptor.
-RA (Return Address)
- A Frame object’s RA member points to the location in the code space
- where control will resume when the function that created the stack
- frame resumes. The Frame object for the top of the stack has a RA
- that is equal to the value in the program counter register at the
- time the Frame object was created. The Frame object for any other
- stack frame has a RA that is found when walking a call stack.
+The following example illustrates how to properly use StackwalkerAPI to
+collect a stack walk from another process at a five second interval.
+Details on the ``ProcDebug`` class, ``getNotificationFD`` method, and
+``handleDebugEvent`` method can be found in
+Section `4.1.1 <#subsubsec:procdebug>`__. See the UNIX man pages for
+more information on the ``select`` system call. Note that this example
+does not include all of the proper error handling and includes that
+should be present when using ``select``.
-= [rectangle, draw, minimum width=3cm, minimum height=1.5em, font=, node
-distance=1.5em] = [rectangle, minimum width=3cm, draw, minimum
-height=1.5em, fill=white, draw=white] = [rectangle] = [rectangle, font=]
-= [draw, -latex’]
+.. code-block:: cpp
-= [rectangle, draw, minimum width=4cm, minimum height=1.5em, font=, node
-distance=1.5em] = [rectangle, minimum width=4cm, draw, minimum
-height=1.5em, fill=white, draw=white] = [rectangle] = [rectangle, font=]
-= [draw, -latex’]
+ Walker *walker = Walker::newWalker(pid);
+ ProcDebug *debugger = (ProcDebug *) walker->getProcessState();
+ std::vector swalk;
+ for (;;) {
+ walker->walkStack(swalk);
+ struct timeval timeout;
+ timeout.tv_sec = 5;
+ timeout.tv_usec = 0;
+ int max = 1;
+ fd_set readfds, writefds, exceptfds;
+ FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&exceptfds);
+ FD_SET(ProcDebug::getNotificationFD(), &readfds);
+ for (;;) {
+ int result = select(max, &readfds, &writefds, &exceptfds, &timeout);
+ if (FD_ISSET(ProcDebug::getNotificationFD(), readfds)) {
+ //Debug event
+ ProcDebug::handleDebugEvent();
+ }
+ if (result == 0) {
+ //Timeout
+ break;
+ }
+ }
+ }
-Figure `[fig:layout] <#fig:layout>`__ shows the relationship between
-application code, stack frames, and Frame objects. In the figure, the
-source code on the left has run through the main and foo functions, and
-into the bar function. It has created the call stack in the center,
-which is shown as a sequence of words growing down. The current values
-of the processor registers, while executing in bar, are shown below the
-call stack. When StackwalkerAPI walks the call stack, it creates the
-Frame objects shown on the right. Each Frame object corresponds to one
-of the stack frames found in the call stack or application registers.
+Extending Stackwalker
+=====================
-The call stack in Figure `[fig:layout] <#fig:layout>`__ is similar to
-one that would be found on the x86 architecture. Details about how the
-call stack is laid out may be different on other architectures, but the
-meanings of the FP, SP, and RA fields in the Frame objects will remain
-the same. The layout of the ARM64 stack may be found in
-Figure `[fig:layout-armv8] <#fig:layout-armv8>`__ as an example of the
-scope of architectural variations.
+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:
-The following four definitions deal with processes involved in
-StackwalkerAPI.
+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.
-Target Process
- The process from which StackwalkerAPI is collecting stackwalks.
+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.
-Host Process
- The process in which StackwalkerAPI code is currently running.
+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.
-First Party Stackwalk
- StackwalkerAPI collects first party stackwalk when it walks a call
- stack in the same address space it is running in, i.e. the target
- process is the same as the host process.
+.. _`subsec:stackwalk-definitions`:
-Third Party Stackwalk
- StackwalkerAPI collects third party stackwalk when it walks the call
- stack in a different address space from the one it is running in,
- i.e. the target process is different from the host process. A third
- party stackwalk is usually done through a debugger interface.
Basic Types
~~~~~~~~~~~
@@ -1401,7 +1447,7 @@ Returns the name of the executable associated with the current process
state.
Class LibraryState
-^^^^^^^^^^^^^^^^^^
+~~~~~~~~~~~~~~~~~~
**Defined in:** ``procstate.h``
@@ -1522,372 +1568,26 @@ This method returns the ``Walker`` object associated with this
This method returns the ``ProcessState`` object associated with this
``SymbolLookup``.
-Callback Interface Default Implementations
-==========================================
-
-StackwalkerAPI provides one or more default implementations of each of
-the callback classes described in Section 3.5. These implementations are
-used by a default configuration of StackwalkerAPI.
-
-.. _`subsec:debugger`:
-
-Debugger Interface
-------------------
-
-This section describes how to use StackwalkerAPI for collecting 3rd
-party stack walks. In 3rd party mode StackwalkerAPI uses the OS’s
-debugger interface to connect to another process and walk its call
-stacks. As part of being a debugger StackwalkerAPI receives and needs to
-handle debug events. When a debugger event occurs, StackwalkerAPI must
-get control of the host process in order to receive the debugger event
-and continue the target process.
-
-To illustrate the complexities with running in 3rd party mode, consider
-the follow code snippet that uses StackwalkerAPI to collect a stack walk
-every five seconds.
+Usage
+=====
-.. code-block:: cpp
-
- Walker *walker = Walker::newWalker(pid);
- std::vector swalk;
- for (;;) {
- walker->walkStack(swalk);
- sleep(5);
- }
-
-StackwalkerAPI is running in 3rd party mode, since it attached to the
-target process, ``pid``. As the target process runs it may be generating
-debug events such a thread creation and destruction, library loads and
-unloads, signals, forking/execing, etc. When one of these debugger
-events is generated the OS will pause the target process and send a
-notice to the host process. The target process will remain paused until
-the host process handles the debug event and resumes the target process.
-
-In the above example the host process is spending almost all of its time
-in the sleep call. If a debugger event happens during the sleep, then
-StackwalkerAPI will not be able to get control of the host process and
-handle the event for up to five seconds. This will cause long pauses in
-the target process and lead to a potentially very large slowdown.
-
-To work around this problem StackwalkerAPI provides a notification file
-descriptor. This file descriptor represents a connection between the
-StackwalkerAPI library and user code. StackwalkerAPI will write a single
-byte to this file descriptor when a debug event occurs, thus notifying
-the user code that it needs to let StackwalkerAPI receive and handle
-debug events. The user code can use system calls such as select to watch
-for events on the notification file descriptor.
-
-The following example illustrates how to properly use StackwalkerAPI to
-collect a stack walk from another process at a five second interval.
-Details on the ``ProcDebug`` class, ``getNotificationFD`` method, and
-``handleDebugEvent`` method can be found in
-Section `4.1.1 <#subsubsec:procdebug>`__. See the UNIX man pages for
-more information on the ``select`` system call. Note that this example
-does not include all of the proper error handling and includes that
-should be present when using ``select``.
-
-.. code-block:: cpp
-
- Walker *walker = Walker::newWalker(pid);
- ProcDebug *debugger = (ProcDebug *) walker->getProcessState();
- std::vector swalk;
- for (;;) {
- walker->walkStack(swalk);
- struct timeval timeout;
- timeout.tv_sec = 5;
- timeout.tv_usec = 0;
- int max = 1;
- fd_set readfds, writefds, exceptfds;
- FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&exceptfds);
- FD_SET(ProcDebug::getNotificationFD(), &readfds);
- for (;;) {
- int result = select(max, &readfds, &writefds, &exceptfds, &timeout);
- if (FD_ISSET(ProcDebug::getNotificationFD(), readfds)) {
- //Debug event
- ProcDebug::handleDebugEvent();
- }
- if (result == 0) {
- //Timeout
- break;
- }
- }
- }
-
-.. _`subsubsec:procdebug`:
-
-Class ProcDebug
-~~~~~~~~~~~~~~~
-
-**Defined in:** ``procstate.h``
-
-Access to StackwalkerAPI’s debugger is through the ``ProcDebug`` class,
-which inherits from the ``ProcessState`` interface. The easiest way to
-get at a ``ProcDebug`` object is to cast the return value of
-``Walker::getProcessState`` into a ``ProcDebug``. C++’s ``dynamic_cast``
-operation can be used to test if a ``Walker`` uses the ``ProcDebug``
-interface:
-
-.. code-block:: cpp
-
- ProcDebug *debugger;
- debugger = dynamic_cast(walker->getProcessState());
- if (debugger != NULL) {
- //3rd party
- ...
- } else {
- //1st party
- ...
- }
-
-In addition to the handling of debug events, described in
-Section `4.1 <#subsec:debugger>`__, the ``ProcDebug`` class provides a
-process control interface; users can pause and resume process or
-threads, detach from a process, and test for events such as process
-death. As an implementation of the ``ProcessState`` class, ``ProcDebug``
-also provides all of the functionality described in
-Section `3.6.4 <#subsec:processstate>`__.
-
-.. code-block:: cpp
-
- virtual bool pause(Dyninst::THR_ID tid = NULL_THR_ID)
-
-This method pauses a process or thread. The paused object will not
-resume execution until ``ProcDebug::resume`` is called. If the ``tid``
-parameter is not ``NULL_THR_ID`` then StackwalkerAPI will pause the
-thread specified by ``tid``. If ``tid`` is ``NULL_THR_ID`` then
-StackwalkerAPI will pause every thread in the process.
-
-When StackwalkerAPI collects a call stack from a running thread it first
-pauses the thread, collects the stack walk, and then resumes the thread.
-When collecting a call stack from a paused thread StackwalkerAPI will
-collect the stack walk and leave the thread paused. This method is thus
-useful for pausing threads before stack walks if the user needs to keep
-the returned stack walk synchronized with the current state of the
+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.
-This method returns ``true`` if successful and ``false`` on error.
-
-.. code-block:: cpp
-
- virtual bool resume(Dyninst::THR_ID tid = NULL_THR_ID)
-
-This method resumes execution on a paused process or thread. This method
-only resumes threads that were paused by the ``ProcDebug::pause`` call,
-using it on other threads is an error. If the ``tid`` parameter is not
-``NULL_THR_ID`` then StackwalkerAPI will resume the thread specified by
-``tid``. If ``tid`` is ``NULL_THR_ID`` then StackwalkerAPI will resume
-all paused threads in the process.
-
-This method returns ``true`` if successful and ``false`` on error.
-
-.. code-block:: cpp
-
- virtual bool detach(bool leave_stopped = false)
-
-This method detaches StackwalkerAPI from the target process.
-StackwalkerAPI will no longer receive debug events on this target
-process and will no longer be able to collect call stacks from it. This
-method invalidates the associated ``Walker`` and ``ProcState`` objects,
-they should be cleaned using C++’s ``delete`` operator after making this
-call. It is an error to attempt to do operations on these objects after
-a detach, and undefined behavior may result.
-
-If the ``leave_stopped`` parameter is ``true`` StackwalkerAPI will
-detach from the process but leave it in a paused state so that it does
-resume progress. This is useful for attaching another debugger back to
-the process for further analysis. The ``leave_stopped`` parameter is not
-supported on the Linux platform and its value will have no affect on the
-detach call.
-
-This method returns ``true`` if successful and ``false`` on error.
-
-.. code-block:: cpp
-
- virtual bool isTerminated()
+.. rli:: https://raw.githubusercontent.com/dyninst/examples/master/stackwalker/this_thread.cpp
+ :language: cpp
+ :linenos:
-This method returns ``true`` if the associated target process has
-terminated and ``false`` otherwise. A target process may terminate
-itself by calling exit, returning from main, or receiving an unhandled
-signal. Attempting to collect stack walks or perform other operations on
-a terminated process is illegal an will lead to undefined behavior.
-
-A process termination will also be signaled through the notification FD.
-Users should check processes for the isTerminated state after returning
-from handleDebugEvent.
-
-.. code-block:: cpp
-
- static int getNotificationFD()
-
-This method returns StackwalkerAPI’s notification FD. The notification
-FD is a file descriptor that StackwalkerAPI will write a byte to
-whenever a debug event occurs that need. If the user code sees a byte on
-this file descriptor it should call ``handleDebugEvent`` to let
-StackwalkerAPI handle the debug event. Example code using
-``getNotificationFD`` can be found in
-Section `4.1 <#subsec:debugger>`__.
-
-StackwalkerAPI will only create one notification FD, even if it is
-attached to multiple 3rd party target processes.
+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:
.. code-block:: cpp
- static bool handleDebugEvent(bool block = false)
-
-When this method is called StackwalkerAPI will receive and handle all
-pending debug events from each 3rd party target process to which it is
-attached. After handling debug events each target process will be
-continued (unless it was explicitly stopped by the ProcDebug::pause
-method) and any bytes on the notification FD will be cleared. It is
-generally expected that users will call this method when a event is sent
-to the notification FD, although it can be legally called at any time.
-
-If the ``block`` parameter is ``true``, then ``handleDebugEvents`` will
-block until it has handled at least one debug event. If the block
-parameter is ``false``, then handleDebugEvents will handle any currently
-pending debug events or immediately return if none are available.
-
-StackwalkerAPI may receive process exit events for target processes
-while handling debug events. The user should check for any exited
-processes by calling ``ProcDebug::isTerminated`` after handling debug
-events.
-
-This method returns ``true`` if successful and ``false`` on error.
-
-.. _`sec:framesteppers`:
-
-FrameSteppers
--------------
-
-**Defined in:** ``framestepper.h``
-
-StackwalkerAPI ships with numerous default implementations of the
-``FrameStepper`` class. Each of these ``FrameStepper`` implementations
-allow StackwalkerAPI to walk a type of call frames.
-Section `3.6.1 <#subsec:defaults>`__ describes which ``FrameStepper``
-implementations are available on which platforms. This sections gives a
-brief description of what each ``FrameStepper`` implementation does.
-Each of the following classes implements the ``FrameStepper`` interface
-described in Section `3.6.2 <#subsec:framestepper>`__, so we do not
-repeat the API description for the classes here.
-
-Several of the ``FrameStepper``\ s use helper classes (see
-``FrameFuncStepper`` as an example). Users can further customize the
-behavior of a ``FrameStepper`` by providing their own implementation of
-these helper classes.
-
-Class FrameFuncStepper
-~~~~~~~~~~~~~~~~~~~~~~
-
-This class implements stack walking through a call frame that is setup
-with the architectures standard stack frame. For example, on x86 this
-``FrameStepper`` will be used to walk through stack frames that are
-setup with a ``push %ebp/mov %esp,%ebp`` prologue.
-
-Class FrameFuncHelper
-^^^^^^^^^^^^^^^^^^^^^
-
-``FrameFuncStepper`` uses a helper class, ``FrameFuncHelper``, to get
-information on what kind of stack frame it’s walking through. The
-``FrameFuncHelper`` will generally use techniques such as binary
-analysis to determine what type of stack frame the ``FrameFuncStepper``
-is walking through. Users can have StackwalkerAPI use their own binary
-analysis mechanisms by providing an implementation of this
-``FrameFuncHelper``.
-
-There are two important types used by ``FrameFuncHelper`` and one
-important function: typedef enum unknown_t=0, no_frame, standard_frame,
-savefp_only_frame, frame_type;
-
-The ``frame_type`` describes what kind of stack frame a function uses.
-If it does not set up a stack frame then ``frame_type`` should be
-``no_frame``. If it sets up a standard frame then ``frame_type`` should
-be ``standard_frame``. The ``savefp_only_frame`` value currently only
-has meaning on the x86 family of systems, and means that a function
-saves the old frame pointer, but does not setup a new frame pointer (it
-has a ``push %ebp`` instruction, but no ``mov %esp,%ebp``). If the
-``FrameFuncHelper`` cannot determine the ``frame_type``, then it should
-be assigned the value ``unknown_t``.
-
-.. code-block:: cpp
-
- typedef enum unknown_s=0, unset_frame, halfset_frame, set_frame frame_state;
-
-The ``frame_state`` type determines the current state of function with a
-stack frame at some point of execution. For example, a function may set
-up a standard stack frame and have a ``frame_type`` of
-``standard_frame``, but execution may be at the first instruction in the
-function and the frame is not yet setup, in which case the
-``frame_state`` will be ``unset_frame``.
-
-If the function sets up a standard stack frame and the execution point
-is someplace where the frame is completely setup, then the
-``frame_state`` should be ``set_frame``. If the function sets up a
-standard frame and the execution point is at a point where the frame
-does not yet exist or has been torn down, then ``frame_state`` should be
-``unset_frame``. The ``halfset_frame`` value of ``frame_state`` is
-currently only meaningful on the x86 family of architecture, and should
-if the function has saved the old frame pointer, but not yet set up a
-new frame pointer.
-
-.. code-block:: cpp
-
- typedef std::pair alloc_frame_t; virtual alloc_frame_t allocatesFrame(Address addr) = 0;
-
-The ``allocatesFrame`` function of ``FrameFuncHelper`` returns a
-``alloc_frame_t`` that describes the frame_type of the function at
-``addr`` and the ``frame_state`` of the function when execution reached
-``addr``.
-
-If ``addr`` is invalid or an error occurs, allocatedFrame should return
-``alloc_frame_t(unknown_t, unknown_s)``.
-
-Class SigHandlerStepper
-~~~~~~~~~~~~~~~~~~~~~~~
-
-The ``SigHandlerStepper`` is used to walk through UNIX signal handlers
-as found on the call stack. On some systems a signal handler generates a
-special kind of stack frame that cannot be walked through using normal
-stack walking techniques.
-
-Class DebugStepper
-~~~~~~~~~~~~~~~~~~
-
-This class uses debug information found in a binary to walk through a
-stack frame. It depends on SymtabAPI to read debug information from a
-binary, then uses that debug information to walk through a call frame.
-
-Most binaries must be built with debug information (``-g`` with ``gcc``)
-in order to include debug information that this ``FrameStepper`` uses.
-Some languages, such as C++, automatically include stackwalking debug
-information for use by exceptions. The ``DebugStepper`` class will also
-make use of this kind of exception information if it is available.
-
-Class AnalysisStepper
-~~~~~~~~~~~~~~~~~~~~~
-
-This class uses dataflow analysis to determine possible stack sizes at
-all locations in a function as well as the location of the frame
-pointer. It is able to handle optimized code with omitted frame pointers
-and overlapping code sequences.
-
-Class StepperWanderer
-~~~~~~~~~~~~~~~~~~~~~
-
-This class uses a heuristic approach to find possible return addresses
-in the stack frame. If a return address is found that matches a valid
-caller of the current function, we conclude it is the actual return
-address and construct a matching stack frame. Since this approach is
-heuristic it can make mistakes leading to incorrect stack information.
-It has primarily been replaced by the ``AnalysisStepper`` described
-above.
-
-Class BottomOfStackStepper
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The ``BottomOfStackStepper`` doesn’t actually walk through any type of
-call frame. Instead it attempts to detect whether the bottom of the call
-stack has been reached. If so, ``BottomOfStackStepper`` will report
-``gcf_stackbottom`` from its ``getCallerFrame`` method. Otherwise it
-will report ``gcf_not_me``. ``BottomOfStackStepper`` runs with a higher
-priority than any other ``FrameStepper`` class.
+ auto *walker = sw::Walker::newWalker(pid);
diff --git a/docs/stackwalk/public/API.rst b/docs/stackwalk/public/API.rst
new file mode 100644
index 0000000000..49cecdc080
--- /dev/null
+++ b/docs/stackwalk/public/API.rst
@@ -0,0 +1,21 @@
+==============
+StackwalkerAPI
+==============
+
+This section gives an API reference for all classes, functions and types in StackwalkerAPI.
+
+.. toctree::
+ :caption: Public API
+ :name: stackwalk-public-api
+ :hidden:
+ :maxdepth: 1
+
+ basetypes.h
+ frame.h
+ framestepper.h
+ local_var.h
+ procstate.h
+ steppergroup.h
+ swk_errors.h
+ symlookup.h
+ walker.h
diff --git a/docs/stackwalk/public/basetypes.h.rst b/docs/stackwalk/public/basetypes.h.rst
new file mode 100644
index 0000000000..9346c6aaf5
--- /dev/null
+++ b/docs/stackwalk/public/basetypes.h.rst
@@ -0,0 +1,5 @@
+basetypes.h
+===========
+
+.. cpp:namespace:: Dyninst::stackwalk
+
diff --git a/docs/stackwalk/public/fig/stackwalker-frame-layout-ARMv8.png b/docs/stackwalk/public/fig/stackwalker-frame-layout-ARMv8.png
new file mode 100644
index 0000000000..951e3636f6
Binary files /dev/null and b/docs/stackwalk/public/fig/stackwalker-frame-layout-ARMv8.png differ
diff --git a/docs/stackwalk/public/fig/stackwalker-frame-layout-x86.png b/docs/stackwalk/public/fig/stackwalker-frame-layout-x86.png
new file mode 100644
index 0000000000..8b95213fe4
Binary files /dev/null and b/docs/stackwalk/public/fig/stackwalker-frame-layout-x86.png differ
diff --git a/docs/stackwalk/public/frame.h.rst b/docs/stackwalk/public/frame.h.rst
new file mode 100644
index 0000000000..cd3ee962e5
--- /dev/null
+++ b/docs/stackwalk/public/frame.h.rst
@@ -0,0 +1,7 @@
+.. _`sec:stackwalk-frame.h.rst`:
+
+frame.h
+=======
+
+.. cpp:namespace:: Dyninst::stackwalk
+
diff --git a/docs/stackwalk/public/framestepper.h.rst b/docs/stackwalk/public/framestepper.h.rst
new file mode 100644
index 0000000000..e1edec9c3c
--- /dev/null
+++ b/docs/stackwalk/public/framestepper.h.rst
@@ -0,0 +1,138 @@
+framestepper.h
+==============
+
+.. cpp:namespace:: Dyninst::stackwalk
+
+FrameSteppers
+-------------
+
+StackwalkerAPI ships with numerous default implementations of the
+``FrameStepper`` class. Each of these ``FrameStepper`` implementations
+allow StackwalkerAPI to walk a type of call frames.
+Section `3.6.1 <#subsec:defaults>`__ describes which ``FrameStepper``
+implementations are available on which platforms. This sections gives a
+brief description of what each ``FrameStepper`` implementation does.
+Each of the following classes implements the ``FrameStepper`` interface
+described in Section `3.6.2 <#subsec:framestepper>`__, so we do not
+repeat the API description for the classes here.
+
+Several of the ``FrameStepper``\ s use helper classes (see
+``FrameFuncStepper`` as an example). Users can further customize the
+behavior of a ``FrameStepper`` by providing their own implementation of
+these helper classes.
+
+Class FrameFuncStepper
+~~~~~~~~~~~~~~~~~~~~~~
+
+This class implements stack walking through a call frame that is setup
+with the architectures standard stack frame. For example, on x86 this
+``FrameStepper`` will be used to walk through stack frames that are
+setup with a ``push %ebp/mov %esp,%ebp`` prologue.
+
+Class FrameFuncHelper
+~~~~~~~~~~~~~~~~~~~~~
+
+``FrameFuncStepper`` uses a helper class, ``FrameFuncHelper``, to get
+information on what kind of stack frame it’s walking through. The
+``FrameFuncHelper`` will generally use techniques such as binary
+analysis to determine what type of stack frame the ``FrameFuncStepper``
+is walking through. Users can have StackwalkerAPI use their own binary
+analysis mechanisms by providing an implementation of this
+``FrameFuncHelper``.
+
+There are two important types used by ``FrameFuncHelper`` and one
+important function: typedef enum unknown_t=0, no_frame, standard_frame,
+savefp_only_frame, frame_type;
+
+The ``frame_type`` describes what kind of stack frame a function uses.
+If it does not set up a stack frame then ``frame_type`` should be
+``no_frame``. If it sets up a standard frame then ``frame_type`` should
+be ``standard_frame``. The ``savefp_only_frame`` value currently only
+has meaning on the x86 family of systems, and means that a function
+saves the old frame pointer, but does not setup a new frame pointer (it
+has a ``push %ebp`` instruction, but no ``mov %esp,%ebp``). If the
+``FrameFuncHelper`` cannot determine the ``frame_type``, then it should
+be assigned the value ``unknown_t``.
+
+.. code-block:: cpp
+
+ typedef enum unknown_s=0, unset_frame, halfset_frame, set_frame frame_state;
+
+The ``frame_state`` type determines the current state of function with a
+stack frame at some point of execution. For example, a function may set
+up a standard stack frame and have a ``frame_type`` of
+``standard_frame``, but execution may be at the first instruction in the
+function and the frame is not yet setup, in which case the
+``frame_state`` will be ``unset_frame``.
+
+If the function sets up a standard stack frame and the execution point
+is someplace where the frame is completely setup, then the
+``frame_state`` should be ``set_frame``. If the function sets up a
+standard frame and the execution point is at a point where the frame
+does not yet exist or has been torn down, then ``frame_state`` should be
+``unset_frame``. The ``halfset_frame`` value of ``frame_state`` is
+currently only meaningful on the x86 family of architecture, and should
+if the function has saved the old frame pointer, but not yet set up a
+new frame pointer.
+
+.. code-block:: cpp
+
+ typedef std::pair alloc_frame_t; virtual alloc_frame_t allocatesFrame(Address addr) = 0;
+
+The ``allocatesFrame`` function of ``FrameFuncHelper`` returns a
+``alloc_frame_t`` that describes the frame_type of the function at
+``addr`` and the ``frame_state`` of the function when execution reached
+``addr``.
+
+If ``addr`` is invalid or an error occurs, allocatedFrame should return
+``alloc_frame_t(unknown_t, unknown_s)``.
+
+Class SigHandlerStepper
+~~~~~~~~~~~~~~~~~~~~~~~
+
+The ``SigHandlerStepper`` is used to walk through UNIX signal handlers
+as found on the call stack. On some systems a signal handler generates a
+special kind of stack frame that cannot be walked through using normal
+stack walking techniques.
+
+Class DebugStepper
+~~~~~~~~~~~~~~~~~~
+
+This class uses debug information found in a binary to walk through a
+stack frame. It depends on SymtabAPI to read debug information from a
+binary, then uses that debug information to walk through a call frame.
+
+Most binaries must be built with debug information (``-g`` with ``gcc``)
+in order to include debug information that this ``FrameStepper`` uses.
+Some languages, such as C++, automatically include stackwalking debug
+information for use by exceptions. The ``DebugStepper`` class will also
+make use of this kind of exception information if it is available.
+
+Class AnalysisStepper
+~~~~~~~~~~~~~~~~~~~~~
+
+This class uses dataflow analysis to determine possible stack sizes at
+all locations in a function as well as the location of the frame
+pointer. It is able to handle optimized code with omitted frame pointers
+and overlapping code sequences.
+
+Class StepperWanderer
+~~~~~~~~~~~~~~~~~~~~~
+
+This class uses a heuristic approach to find possible return addresses
+in the stack frame. If a return address is found that matches a valid
+caller of the current function, we conclude it is the actual return
+address and construct a matching stack frame. Since this approach is
+heuristic it can make mistakes leading to incorrect stack information.
+It has primarily been replaced by the ``AnalysisStepper`` described
+above.
+
+Class BottomOfStackStepper
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ``BottomOfStackStepper`` doesn’t actually walk through any type of
+call frame. Instead it attempts to detect whether the bottom of the call
+stack has been reached. If so, ``BottomOfStackStepper`` will report
+``gcf_stackbottom`` from its ``getCallerFrame`` method. Otherwise it
+will report ``gcf_not_me``. ``BottomOfStackStepper`` runs with a higher
+priority than any other ``FrameStepper`` class.
\ No newline at end of file
diff --git a/docs/stackwalk/public/local_var.h.rst b/docs/stackwalk/public/local_var.h.rst
new file mode 100644
index 0000000000..00d040fdef
--- /dev/null
+++ b/docs/stackwalk/public/local_var.h.rst
@@ -0,0 +1,5 @@
+local_var.h
+===========
+
+.. cpp:namespace:: Dyninst::stackwalk
+
diff --git a/docs/stackwalk/public/procstate.h.rst b/docs/stackwalk/public/procstate.h.rst
new file mode 100644
index 0000000000..64b694d24f
--- /dev/null
+++ b/docs/stackwalk/public/procstate.h.rst
@@ -0,0 +1,141 @@
+procstate.h
+===========
+
+.. cpp:namespace:: Dyninst::stackwalk
+
+Class ProcDebug
+~~~~~~~~~~~~~~~
+
+Access to StackwalkerAPI’s debugger is through the ``ProcDebug`` class,
+which inherits from the ``ProcessState`` interface. The easiest way to
+get at a ``ProcDebug`` object is to cast the return value of
+``Walker::getProcessState`` into a ``ProcDebug``. C++’s ``dynamic_cast``
+operation can be used to test if a ``Walker`` uses the ``ProcDebug``
+interface:
+
+.. code-block:: cpp
+
+ ProcDebug *debugger;
+ debugger = dynamic_cast(walker->getProcessState());
+ if (debugger != NULL) {
+ //3rd party
+ ...
+ } else {
+ //1st party
+ ...
+ }
+
+In addition to the handling of debug events, described in
+Section `4.1 <#subsec:debugger>`__, the ``ProcDebug`` class provides a
+process control interface; users can pause and resume process or
+threads, detach from a process, and test for events such as process
+death. As an implementation of the ``ProcessState`` class, ``ProcDebug``
+also provides all of the functionality described in
+Section `3.6.4 <#subsec:processstate>`__.
+
+.. code-block:: cpp
+
+ virtual bool pause(Dyninst::THR_ID tid = NULL_THR_ID)
+
+This method pauses a process or thread. The paused object will not
+resume execution until ``ProcDebug::resume`` is called. If the ``tid``
+parameter is not ``NULL_THR_ID`` then StackwalkerAPI will pause the
+thread specified by ``tid``. If ``tid`` is ``NULL_THR_ID`` then
+StackwalkerAPI will pause every thread in the process.
+
+When StackwalkerAPI collects a call stack from a running thread it first
+pauses the thread, collects the stack walk, and then resumes the thread.
+When collecting a call stack from a paused thread StackwalkerAPI will
+collect the stack walk and leave the thread paused. This method is thus
+useful for pausing threads before stack walks if the user needs to keep
+the returned stack walk synchronized with the current state of the
+thread.
+
+This method returns ``true`` if successful and ``false`` on error.
+
+.. code-block:: cpp
+
+ virtual bool resume(Dyninst::THR_ID tid = NULL_THR_ID)
+
+This method resumes execution on a paused process or thread. This method
+only resumes threads that were paused by the ``ProcDebug::pause`` call,
+using it on other threads is an error. If the ``tid`` parameter is not
+``NULL_THR_ID`` then StackwalkerAPI will resume the thread specified by
+``tid``. If ``tid`` is ``NULL_THR_ID`` then StackwalkerAPI will resume
+all paused threads in the process.
+
+This method returns ``true`` if successful and ``false`` on error.
+
+.. code-block:: cpp
+
+ virtual bool detach(bool leave_stopped = false)
+
+This method detaches StackwalkerAPI from the target process.
+StackwalkerAPI will no longer receive debug events on this target
+process and will no longer be able to collect call stacks from it. This
+method invalidates the associated ``Walker`` and ``ProcState`` objects,
+they should be cleaned using C++’s ``delete`` operator after making this
+call. It is an error to attempt to do operations on these objects after
+a detach, and undefined behavior may result.
+
+If the ``leave_stopped`` parameter is ``true`` StackwalkerAPI will
+detach from the process but leave it in a paused state so that it does
+resume progress. This is useful for attaching another debugger back to
+the process for further analysis. The ``leave_stopped`` parameter is not
+supported on the Linux platform and its value will have no affect on the
+detach call.
+
+This method returns ``true`` if successful and ``false`` on error.
+
+.. code-block:: cpp
+
+ virtual bool isTerminated()
+
+This method returns ``true`` if the associated target process has
+terminated and ``false`` otherwise. A target process may terminate
+itself by calling exit, returning from main, or receiving an unhandled
+signal. Attempting to collect stack walks or perform other operations on
+a terminated process is illegal an will lead to undefined behavior.
+
+A process termination will also be signaled through the notification FD.
+Users should check processes for the isTerminated state after returning
+from handleDebugEvent.
+
+.. code-block:: cpp
+
+ static int getNotificationFD()
+
+This method returns StackwalkerAPI’s notification FD. The notification
+FD is a file descriptor that StackwalkerAPI will write a byte to
+whenever a debug event occurs that need. If the user code sees a byte on
+this file descriptor it should call ``handleDebugEvent`` to let
+StackwalkerAPI handle the debug event. Example code using
+``getNotificationFD`` can be found in
+Section `4.1 <#subsec:debugger>`__.
+
+StackwalkerAPI will only create one notification FD, even if it is
+attached to multiple 3rd party target processes.
+
+.. code-block:: cpp
+
+ static bool handleDebugEvent(bool block = false)
+
+When this method is called StackwalkerAPI will receive and handle all
+pending debug events from each 3rd party target process to which it is
+attached. After handling debug events each target process will be
+continued (unless it was explicitly stopped by the ProcDebug::pause
+method) and any bytes on the notification FD will be cleared. It is
+generally expected that users will call this method when a event is sent
+to the notification FD, although it can be legally called at any time.
+
+If the ``block`` parameter is ``true``, then ``handleDebugEvents`` will
+block until it has handled at least one debug event. If the block
+parameter is ``false``, then handleDebugEvents will handle any currently
+pending debug events or immediately return if none are available.
+
+StackwalkerAPI may receive process exit events for target processes
+while handling debug events. The user should check for any exited
+processes by calling ``ProcDebug::isTerminated`` after handling debug
+events.
+
+This method returns ``true`` if successful and ``false`` on error.
\ No newline at end of file
diff --git a/docs/stackwalk/public/steppergroup.h.rst b/docs/stackwalk/public/steppergroup.h.rst
new file mode 100644
index 0000000000..c05f9cae02
--- /dev/null
+++ b/docs/stackwalk/public/steppergroup.h.rst
@@ -0,0 +1,5 @@
+steppergroup.h
+==============
+
+.. cpp:namespace:: Dyninst::stackwalk
+
diff --git a/docs/stackwalk/public/swk_errors.h.rst b/docs/stackwalk/public/swk_errors.h.rst
new file mode 100644
index 0000000000..d39f7e2bed
--- /dev/null
+++ b/docs/stackwalk/public/swk_errors.h.rst
@@ -0,0 +1,5 @@
+swk_errors.h
+============
+
+.. cpp:namespace:: Dyninst::stackwalk
+
diff --git a/docs/stackwalk/public/symlookup.h.rst b/docs/stackwalk/public/symlookup.h.rst
new file mode 100644
index 0000000000..2fecdcf75e
--- /dev/null
+++ b/docs/stackwalk/public/symlookup.h.rst
@@ -0,0 +1,5 @@
+symlookup.h
+===========
+
+.. cpp:namespace:: Dyninst::stackwalk
+
diff --git a/docs/stackwalk/public/walker.h.rst b/docs/stackwalk/public/walker.h.rst
new file mode 100644
index 0000000000..260cc65429
--- /dev/null
+++ b/docs/stackwalk/public/walker.h.rst
@@ -0,0 +1,5 @@
+walker.h
+========
+
+.. cpp:namespace:: Dyninst::stackwalk
+