Skip to content

Repository files navigation

libDAP - Debug Adapter Protocol Implementation

License: MIT C Standard Build System

A robust, production-ready Debug Adapter Protocol (DAP) implementation written in C, designed for integration into CPU emulators, debuggers, and debugging tools.

This project implements a Debug Adapter Protocol (DAP) server and client - to be used for whatever, but primarily made to be included in a CPU emulator.

πŸš€ Features

  • Complete DAP Implementation: Full server and client implementation following the Debug Adapter Protocol specification
  • Advanced Threading Architecture: Multi-threaded DAP client with responsive UI and non-blocking operations
  • Professional Memory Examination: Industry-standard hex dump tools with base64 decoding
  • Smart Parameter Validation: Intelligent command validation with helpful error messages and auto-completion
  • Beautiful Table Formatting: Professional Unicode table output for threads, variables, stack traces, and scopes
  • Callback Architecture: Clean separation between protocol handling and debugger implementation
  • Production Ready: Used in real-world projects like nd100x
  • Cross-Platform: Supports Linux, Windows, and other POSIX-compliant systems
  • Memory Safe: Comprehensive error handling and memory management

Core Features

  • Dual Architecture Support:
    • Single-threaded debugger implementation (optimized for CPU emulation)
    • Multi-threaded DAP client with responsive UI
  • Complete Debug Command Support:
    • Launch/Attach with parameter validation
    • Step In/Out/Over with smart threading
    • Continue/Pause with state management
    • Breakpoints with comprehensive control
    • Stack trace with beautiful formatting
    • Thread information with caching
    • Variables inspection with hierarchical display
    • Scopes examination with reference tracking
    • Memory dump functionality with professional hex output
    • Disassembly support
  • Custom command extensions:
    • Terminal console capture/input (consoleEnable / consoleWrite)
    • Bulk symbol fetch (symbolList)
    • CPU instruction trace ring (setCpuTracing / getCpuTraceRing) β€” record the last N retired instructions and read them back after a stop; the forward-only substitute for reverse execution
  • Smart User Experience:
    • Parameter validation with helpful error messages
    • Cached values for seamless command chaining
    • Auto-completion and smart defaults
    • Real-time event processing
    • Professional table formatting
  • Advanced Communication:
    • TCP-based communication
    • Thread-safe message handling
    • Non-blocking operations
    • Event-driven architecture

πŸ“¦ Components

⚠️ Two debuggers ship in this repo β€” don't confuse them

Binary Kind Source dir Build dir How to build & run
dap_debugger / dap_debugger_threaded Terminal (readline TUI) src/dap_debugger/ build/bin/ make debug (root) β†’ make run
dap_gui_debugger Visual GUI (ImGui + SDL3) β€” see tools/dap-debugger/README.md (incl. visual register-watch dialog) tools/dap-debugger/src/ tools/dap-debugger/build/ cd tools/dap-debugger && make β†’ make run

The root Makefile (make, make run, make runsrv) only builds and runs the terminal clients. It will not build the GUI.

The GUI has its own Makefile under tools/dap-debugger/. You must cd into that directory first. The GUI binary lives at tools/dap-debugger/build/dap_gui_debugger and connects to a running DAP server (nd100x or dap_mock_server) β€” start the server first.

Quick reference:

# Terminal TUI debugger (root)
cd ~/repos/libdap
make debug                    # builds dap_debugger and dap_debugger_threaded

# Visual GUI debugger (subdir)
cd ~/repos/libdap/tools/dap-debugger
make                          # build dap_gui_debugger
make run                      # build + connect to localhost:5555 (nd100x default)
make run-mock                 # build + connect to mock server on 4711
make rebuild                  # clean + build

DAP Mock Server (Mock of a debugger backend. Use as example to integrate into your architecture)

  • src/dap_mock_server/dap_mock_server.c: Main server implementation
  • src/dap_mock_server/dap_mock_server.h: Main server implementation header file
  • src/dap_mock_server/dap_mock_server_main.c: Server entry point

DAP Client (Advanced test implementation demonstrating the DAPLibrary integration)

The DAP Client provides both single-threaded and multi-threaded implementations to test and demonstrate the DAPLibrary integration:

Available Clients

  • dap_debugger: Single-threaded client (original implementation)
  • dap_debugger_threaded: Multi-threaded client with advanced features (recommended)

Core Components

  • src/dap_debugger/dap_debugger.c: Main client implementation and command registry
  • src/dap_debugger/dap_debugger_main.c: Single-threaded client entry point
  • src/dap_debugger/dap_debugger_main_threaded.c: Multi-threaded client entry point
  • src/dap_debugger/dap_debugger_commands.c: Command implementations including memory dump

Threading Architecture (dap_debugger_threaded)

  • src/dap_debugger/dap_debugger_threads.c: Thread management and communication
  • src/dap_debugger/dap_client_thread.c: DAP communication thread with smart validation
  • src/dap_debugger/dap_ui_thread.c: User interface thread with real-time input
  • src/dap_debugger/dap_debugger_threads.h: Threading interfaces and data structures

User Interface Components

  • src/dap_debugger/dap_debugger_ui.c: User interface implementation
  • src/dap_debugger/dap_debugger_ui.h: UI interface definitions

Response Formatting System

  • src/dap_debugger/dap_response_formatter.c: Professional table formatting with Unicode
  • src/dap_debugger/dap_response_formatter.h: Formatter interfaces and column definitions

Help System

  • src/dap_debugger/dap_debugger_help.c: Comprehensive help command implementation
  • src/dap_debugger/dap_debugger_help.h: Help system interface

πŸ“¦ Installation

Prerequisites

Ubuntu/Debian:

sudo apt update
sudo apt install build-essential cmake libcjson-dev libreadline-dev

Fedora/RHEL:

sudo dnf install gcc cmake cjson-devel readline-devel

macOS:

brew install cmake cjson readline

Dependencies

  • cJSON library:

    # Ubuntu/Debian
    sudo apt update
    sudo apt install libcjson-dev
    
    # Fedora/RHEL
    sudo dnf install cjson-devel
  • readline library:

    # Ubuntu/Debian
    sudo apt install libreadline-dev
    
    # Fedora/RHEL
    sudo dnf install readline-devel

πŸ”§ Building the Project

CMake (Primary Build System)

  1. Generate the build system:
cmake -B build
-- Using system cJSON library
-- Configuring done
-- Generating done
-- Build files have been written to: /home/ronny/repos/libdap/build
  1. Compile the project:
cmake --build build
  1. The compiled binaries will be in the build directory.

Build Configuration Options

# Debug build with executables
cmake -B build -DCMAKE_BUILD_TYPE=Debug -DBUILD_EXECUTABLES=ON
cmake --build build

# Release build with executables
cmake -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_EXECUTABLES=ON
cmake --build build

Cleaning the Build

To clean the build and start fresh:

# Remove all build artifacts
cmake --build build --target clean

# Or to remove the entire build directory
rm -rf build

Using Make (CMake Wrapper)

A Makefile is included to simplify the process if you prefer using make.

$make help

libDAP makefile - CMake wrapper
-------------------------------------------------------------------------------
Targets:
  all (default) - Same as 'debug'
  debug         - Build debug version
  release       - Build release version
  sanitize      - Build with address sanitizer
  clean         - Remove build directories
  runsrv        - Build and run mock server
  rund          - Build and run the debugger
  help          - Show this help

This Makefile is a wrapper around CMake. If you prefer, you can use CMake directly:
  cmake -B build
  cmake --build build

Make Targets

# Debug build with test tools
make debug

# Release build
make release

# Run with memory checking
make runsrv  # Start server with valgrind
make run     # Start TERMINAL debugger with valgrind

# Clean everything
make clean

Note: these targets build the terminal debugger only. To build the visual GUI (dap_gui_debugger), use the separate Makefile in tools/dap-debugger/ β€” see the "Two debuggers" callout above.

πŸ”§ Quick Start

Using the Library in Your Project

#include <dap_server.h>

// 1. Create server configuration
DAPServerConfig config = {
    .program_path = "/path/to/your/debuggee",
    .transport = {
        .type = DAP_TRANSPORT_TCP,
        .tcp = { .port = 4711 }
    }
};

// 2. Create and initialize server
DAPServer *server = dap_server_create(&config);

// 3. Register your debugger callbacks
dap_server_register_command_callback(server, DAP_CMD_LAUNCH, my_launch_callback);
dap_server_register_command_callback(server, DAP_CMD_STEP_IN, my_step_callback);
dap_server_register_command_callback(server, DAP_CMD_CONTINUE, my_continue_callback);

// 4. Run the server
dap_server_run(server);

// 5. Cleanup
dap_server_free(server);

Testing with Included Tools

Run the mock server:

./build/bin/dap_mock_server --debug

Connect with the advanced threaded debugger (recommended):

./build/bin/dap_debugger_threaded

Or use the single-threaded debugger:

./build/bin/dap_debugger /path/to/program.exe --debug

Memory Examination Examples

Once connected to a debug session, you can examine memory with professional hex dump output:

# Basic memory examination (16 bytes default)
dap# x 0x401000

# Examine larger memory blocks
dap# x 0x401000 256

# Use symbol names
dap# memory main 64

# Examine with offset
dap# readMemory 0x401000 32 8

Example output:

Memory Dump:
Address: 401000 (64 bytes)

Address  | 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | ASCII
---------|--------------------------------------------------|----------------
00401000 | 48 89 e5 48 83 ec 20 89 7d fc c7 45 f8 00 00 00 | H..H.. .}..E....
00401010 | 00 8b 45 f8 83 c0 01 89 45 f8 83 7d f8 0a 7e ef | ..E.....E..}..~.
00401020 | 8b 45 fc 48 98 48 8d 15 00 00 00 00 48 01 d0 0f | .E.H.H......H...
00401030 | b6 00 84 c0 75 02 eb 05 e8 00 00 00 00 c9 c3 55 | ....u..........U

Smart Command Features

The threaded debugger includes intelligent features:

# Commands with parameter validation
dap# variables
Error: variables command requires a variables reference (get from scopes)

# Smart caching - commands remember previous results
dap# threads          # Shows available threads, caches thread ID
dap# stackTrace       # Uses cached thread ID automatically
dap# scopes           # Uses cached frame ID from stackTrace
dap# variables        # Uses cached variables reference from scopes

# Debug mode for troubleshooting
dap# debugmode        # Toggle debug output

# Server capabilities inspection (works without connection)
dap# srv              # Show DAP server capabilities and protocol compliance
dap# capabilities     # Full command name for server info
dap# server           # Alternative alias

Complete Command Reference

Execution Control:

  • continue (c, cont) - Resume execution
  • next (n, over) - Step over next line
  • stepIn (s, step) - Step into function call
  • stepOut (o, step-out) - Step out of current function
  • pause (p) - Pause execution

Program Control:

  • launch (r, run) - Launch debug session
  • attach - Attach to running process
  • restart - Restart debug session
  • disconnect - Disconnect from debugger
  • terminate - Terminate debuggee

Breakpoints:

  • setBreakpoints (b, break) - Set line breakpoints
  • setExceptionBreakpoints (ex, exception) - Set exception breakpoints

Watchpoints (watch, w):

  • watch <addr> [read|write|readwrite] - Memory watchpoint (prefix phys/ispace/dspace)
  • watch reg:<NAME> - Break when a CPU register changes
  • watch reg:<NAME> == 0x50000204 - Break when a register equals a value (!= < > <= >= too)
  • watch reg:<NAME> bit 27 -> 1 - Break when bit 27 goes 0β†’1 (-> 0, changed also)
  • info watchpoints (info w) - List watchpoints, including their conditions
  • See docs/register-watchpoints.md for register watches (reg:NAME + value/bit conditions)

Information & Inspection:

  • threads (t) - List all threads
  • stackTrace (bt, backtrace) - Show call stack
  • scopes (s) - Show variable scopes for current frame
  • variables (v, vars) - Show variables with hierarchy
  • evaluate (e, eval) - Evaluate expressions
  • source (l, list) - Get source code content

Memory & Assembly:

  • readMemory (x, memory) - Professional hex dump of memory
  • disassemble (da) - Disassemble code at memory location

System & Utility:

  • capabilities (srv, server) - Show DAP server capabilities (works without connection)
  • debugmode (dm) - Toggle debug mode for troubleshooting
  • help (?, h) - Show command help
  • exit (q, quit) - Exit the debugger

πŸ—οΈ Architecture

libDAP uses a clean callback-based architecture that separates DAP protocol handling from debugger implementation:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   DAP Client    │───▢│   libDAP Core   │───▢│ Your Debugger   β”‚
β”‚ (VS Code, etc.) β”‚    β”‚ (Protocol Layer)β”‚    β”‚ Implementation  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
  • libDAP Core: Handles all DAP protocol details, message parsing, and transport
  • Your Implementation: Provides callbacks for actual debugging operations
  • Clean Interface: No need to understand DAP internals

πŸ“Š Current Status

  • βœ… Production Ready: Core functionality is stable and battle-tested
  • βœ… Advanced Threading: Multi-threaded DAP client with responsive UI
  • βœ… Professional Memory Tools: Industry-standard hex dump with base64 decoding
  • βœ… Smart User Experience: Parameter validation, caching, and auto-completion
  • βœ… Beautiful Output: Unicode table formatting for all debug data
  • βœ… Complete Command Set: Full DAP protocol support with validation
  • βœ… Dual Architecture: Both single and multi-threaded implementations
  • βœ… Memory Management: Comprehensive error handling and safety
  • βœ… Build System: Robust CMake-based build with multiple targets
  • βœ… Debug Infrastructure: Advanced logging and troubleshooting tools

⚠️ Known Issues

  • Some compiler warnings about variadic macros (non-critical)
  • Linter warnings about struct sigaction (non-critical)

πŸ›£οΈ Future Improvements

  • βœ… Add memory inspection capabilities Completed: Professional hex dump tools implemented
  • βœ… Improve error handling and recovery Completed: Smart validation and caching implemented
  • βœ… Add support for more debug commands Completed: Full DAP command set with validation
  • Implement breakpoint conditions and advanced breakpoint features
  • Add comprehensive unit test suite
  • Expand multi-platform support and testing
  • Add performance profiling and optimization tools
  • Implement advanced debugging features (data breakpoints, tracepoints)
  • Add plugin architecture for custom formatters
  • Integrate with popular IDEs and editors

🀝 Contributing

We welcome contributions! Here's how to get started:

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Make your changes: Follow the existing code style
  4. Add tests: Ensure your changes are tested
  5. Commit: git commit -m 'Add amazing feature'
  6. Push: git push origin feature/amazing-feature
  7. Submit a Pull Request

Code Style

  • Use C99 standard
  • Follow existing naming conventions (snake_case)
  • Add documentation for public APIs
  • Include error handling
  • Use meaningful commit messages

Testing

  • Test on multiple platforms when possible
  • Include unit tests for new functionality
  • Verify with valgrind for memory issues
  • Test integration with mock server

πŸ“‹ Real-World Usage

libDAP is actively used in:

  • nd100x: A CPU emulator project using the server component

Using libDAP in your project? Let us know by opening an issue!

πŸ“Š Project Status

  • βœ… Stable: Core functionality is production-ready
  • βœ… Maintained: Actively developed and maintained
  • ⚠️ API Changes: Minor breaking changes may occur (see CHANGELOG.md)
  • πŸ”„ Semantic Versioning: Following SemVer starting from v1.0.0

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ†˜ Support

πŸ™ Acknowledgments

  • Debug Adapter Protocol specification by Microsoft
  • Contributors and users providing feedback
  • The open-source community

Note: This library implements the Debug Adapter Protocol as specified by Microsoft. For protocol details, see the official DAP specification.

About

Debug Adapter Protocol (DAP) library in C

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages