Debugging API examples

These examples demonstrate how to implement a debugger with the help of Win32 Debugging API functions (DebugActiveProcess, WaitForDebugEvent, etc.).

Here is a short list of topics addressed in the examples:

  • How to start debugging (launch the debuggee, or attach to the running process)
  • How to implement the debugging loop and process debug events
  • What to do with various handles passed to the debugger together with debug events
  • How to obtain the path and name for modules loaded by the debuggee process
  • How to load/unload symbols for a module
  • How to display progress messages from the symbol engine while it is searching for symbols (similar to noisy mode in WinDbg)
  • How to walk and show the call stack of the debuggee process when it is stopped on a debug event

The examples also include a simple but useful symbol engine class (based on DbgHelp), which allows to load/unload symbols for a module, walk call stacks, analyze debug information (e.g. lookup a symbol by address and find the corresponding source file/line information). It is also possible to receive troubleshooting and progress messages from DbgHelp while it is searching for symbols. Note that while the examples use the symbol engine in a debugger, it is also possible to use it in-process (e.g. to walk the call stack of the current thread).

How to build and run the examples

List of examples

DebugEvents.cpp This example shows how to launch the debuggee or attach to an already running process, and how to implement the debugging loop and handle debug events. The example displays the raw data passed to the debugger with the debug events, which makes possible to see the exact contents of various debug event related structures. It also explains what handles are passed to the debugger by the operating system, and how to handle them properly (e.g. what handles should be closed by the debugger and what should not be closed).
BaseDbg.cpp This example extends the previous one with the possibility to display meaningful information about various debug events received by the debugger. It also shows how to obtain the paths and names of the modules loaded by the debuggee process (one of several possible approaches is shown, which utilizes the module's file handle and PSAPI library to obtain the module name).
SymLoadDbg.cpp This example extends the previous examples with the possibility to load symbols for the modules loaded by the debuggee process. After the symbols have been loaded, the debugger will show additional information about the origin of the loaded symbols (CodeView, DBG, PDB, etc.). The example is also capable of receiving and showing the troubleshooting and progress messages from DbgHelp debug engine (which is similar to noisy mode in WinDBG).
ExcepMon.cpp This example shows how to monitor exceptions in the debuggee process. When an exception occurs in the debuggee, the debugger walks the call stack and utilizes the symbol engine to display function names and source file/line information about stack frames.


Download all examples

Symbol engine class

Here are the files that implement the symbol engine class. They are used by SymLoadDbg and ExcepMon examples.

SymbolEngine.h Header file
SymbolEngine.cpp Implementation file


Download all examples

How to build and run the examples

The following steps are needed to build the examples:

DebugEvents and BaseDbg examples

Create a console project and add the example's source file to the project. After you have built the project, the example is ready to run.
Command line options are described at the beginning of the example's source file.

SymLoadDbg and ExcepMon examples

1. Find the latest versions of DbgHelp.dll, DbgHelp.h and DbgHelp.lib files.

The latest versions of these files are always available with Debugging Tools for Windows package. Download and install Debugging Tools for Windows (when installing, choose custom installation and install SDK).

2. Configure Visual Studio to find DbgHelp.h and DbgHelp.lib files.

These files are supplied with Visual Studio and Platform SDK, but it is necessary to use the latest files – the files that come with Debugging Tools for Windows. Thus it is necessary to configure Visual Studio include and library directories so that the latest files will be found first.

Use the following directories:
Include -> %DebuggingTools%\sdk\inc
Library -> %DebuggingTools%\sdk\lib\i386

3. Create a console project and add the example's source file to the project. Also add SymbolEngine.h and SymboleEngine.cpp files to the project.

4. When the project is built, make sure that the executable can find the latest version of DbgHelp.dll.

Copy DbgHelp.dll from the installation directory of Debugging Tools for Windows to the directory where the example executable resides.

Note: The examples can use symbol server. If you want to let them use symbol server, make sure that SymSrv.dll is also available in the directory where the example executable resides. SymSrv.dll can also be taken from the installation directory of Debugging Tools for Windows.

Command line options of the examples are described at the beginning of the example's source file.