RAD Debugger Documentation

repository·master·Indexed 27 days ago

https://github.com/epicgames/raddebugger

A high-performance, native, graphical debugger for Windows x64. The project includes the RAD Debug Info (RDI) custom debug information format and the RAD Linker, a high-speed linker for generating x64 PE/COFF binaries optimized for massive scale projects. It features the radbin utility for RDI conversion and supports local-machine debugging using PDBs.

Tokens
4K
Snippets
4
Records
18
Agent score
92%

What's inside RAD Debugger

  1. Overview of the RAD Debugger Project

    master

    The RAD Debugger is a native, user-mode, multi-process, graphical debugger. It currently supports local-machine Windows x64 debugging using PDBs. The project also includes two related technologies:

    1. RAD Debug Info (RDI) Format: A custom debug information format used by the debugger. It can convert PDB (and eventually PE/ELF with DWARF) into RDI on-demand.
    2. RAD Linker: A high-performance linker for generating x64 PE/COFF binaries, optimized for extremely large executables. It is compatible with MSVC command-line syntax.
  2. Overview of xxHash Digest Algorithms

    master

    xxHash is a family of non-cryptographic, high-speed digest algorithms designed to produce a unique 'fingerprint' or digest from an arbitrary length message. It supports optional seed values and is optimized for different architectures:

    • XXH32: Optimized for 32-bit machines.
    • XXH64: Optimized for 64-bit machines.
    • XXH3: Optimized for performance using vector operations; available in 64-bit (XXH3_64bits) and 128-bit (XXH3_128bits) variants.

    Note: xxHash is non-cryptographic. It is not intended to prevent intentional collisions or to resist attacks where a message is crafted to produce a specific digest.

  3. Overview of xxHash algorithms

    master

    xxHash is a high-performance hash algorithm that operates at RAM speed limits. It provides several variants depending on the required hash width and performance characteristics:

    • XXH32: Generates 32-bit hashes using 32-bit arithmetic.
    • XXH64: Generates 64-bit hashes using 64-bit arithmetic.
    • XXH3: Generates 64-bit or 128-bit hashes (the 128-bit variant is called XXH128) using vectorized arithmetic. It is optimized for both large and small inputs.
  4. Understand the RAD Debugger codebase layers and namespaces

    master

    The codebase is organized into a directed acyclic graph of layers, which correspond to folders in the src directory. To identify which layer a piece of code belongs to, the project uses a C-style naming convention where a short prefix (1-3 characters) followed by an underscore is used as a namespace.

    Namespace Naming Conventions:

    • Types, enum values, and certain macros: Capitalized (e.g., CV_ for codeview).
    • Functions and global variables: Lowercase (e.g., cv_ for codeview).

    Key Layer Categories:

    • Standalone Libraries: Folders prefixed with lib_ (e.g., lib_rdi) are designed to be used independently and do not depend on other codebase layers.
    • Core Debugger Layers: Includes dbg_engine (D_) for core logic, ctrl (CTRL_) for process control, and raddbg (RD_) for the graphical frontend.
    • Format Parsers: Specific layers for pdb (PDB_), elf (ELF_), dwarf (DW_), coff (COFF_), and pe (PE_).
    • RDI Conversion Layers: Layers like rdi_from_pdb (P2R_) and rdi_from_coff (C2R_) handle converting standard debug formats to the RAD Debug Info (RDI) format.
  5. Build the RAD Debugger project

    master

    Navigate to the root directory of the codebase and use the build.bat script.

    Build Debugger (Default)

    To build the debugger in debug mode (no optimizations, slower performance):

    build

    To build the debugger in release mode (optimized):

    build release

    Build Other Components

    You can specify which component to build by passing its name as an argument:

    • RAD Linker: build radlink [release]
    • radbin utility: build radbin [release]

    Example for building the linker in release mode:

    build radlink release

    Successful builds will place artifacts in the build folder at the root of the codebase.

    build
    build release
    build radlink release
    build radbin release
  6. Performance Considerations for xxHash

    master

    To achieve optimal performance when choosing an xxHash variant, consider the target architecture:

    • 64-bit Systems: XXH64 is generally faster than XXH32. XXH3 is the fastest option when vector operations (SIMD) are available.
    • 32-bit Systems: XXH32 is faster than XXH64 because XXH64 relies heavily on 64-bit arithmetic which is less efficient on 32-bit CPUs.
    • Streaming: The algorithm allows for streaming input, but an internal buffer must be used to ensure data is presented in full stripes (16 bytes for XXH32, 32 bytes for XXH64) to maintain speed.
  7. Set up the development environment for RAD Debugger

    master

    Development is currently only supported on x64 Windows.

    1. Install Required Tools

    Install Microsoft C/C++ Build Tools v15 (2017) or later. This provides the Windows SDK, MSVC compiler, and linker. You may also use Clang if the Windows SDK is installed.

    2. Configure Build Environment

    Open a terminal that can call MSVC or Clang. The easiest way is to use the x64 Native Tools Command Prompt for VS <year> from the Windows Start Menu. Alternatively, call vcvarsall.bat x64 from a standard command prompt.

    Verify the compiler is accessible by running:

    cl
  8. Configure xxHash via build macros

    master

    You can modify libxxhash behavior at compile time using several macros. Key macros include:

    • XXH_INLINE_ALL: Makes all functions inline for speed, especially effective when key length is a compile-time constant.
    • XXH_NAMESPACE: Prefixes all symbols with the value of XXH_NAMESPACE to avoid collisions.
    • XXH_VECTOR: Manually select a vector instruction set. Options: XXH_SCALAR, XXH_SSE2, XXH_AVX2, XXH_AVX512, XXH_NEON, and XXH_VSX.
    • XXH_NO_STREAM: Disables the streaming API, limiting the library to single-shot variants only.
    • XXH_NO_STDLIB: Disables <stdlib.h> functions like malloc() and free(). Useful for embedded environments. Note that XXH*_createState() will return NULL in this mode.
    • XXH_SIZE_OPT: Controls size optimization (0: speed, 1: size/speed balance, 2: smallest possible code).
    • XXH_DEBUGLEVEL: Set to $\ge 1$ to enable assert() statements for debugging.
  9. Report a security vulnerability in xxHash

    master

    If you discover a security vulnerability in the xxHash component, do not disclose it as a public issue. Report it privately via a security advisory to allow time for a patch to be developed before public exposure.

    Use the following link to disclose vulnerabilities: security advisory

    Note that this project is maintained by volunteers; please allow at least 90 days for a fix to be addressed before public disclosure.

  10. Use xxHash streaming API

    master

    To hash data incrementally (e.g., reading from a file in chunks), use the streaming API. This involves creating a state, resetting it with a seed, updating it with data chunks, and finally digesting the result.

    #include "stdlib.h"   /* abort() */
    #include "xxhash.h"
    
    XXH64_hash_t calcul_hash_streaming(FileHandler fh)
    {
        /* create a hash state */
        XXH64_state_t* const state = XXH64_createState();
        if (state==NULL) abort();
    
        size_t const bufferSize = SOME_SIZE;
        void* const buffer = malloc(bufferSize);
        if (buffer==NULL) abort();
    
        /* Initialize state with selected seed */
        XXH64_hash_t const seed = 0;   /* or any other value */
        if (XXH64_reset(state, seed) == XXH_ERROR) abort();
    
        /* Feed the state with input data, any size, any number of times */
        // ...
        while ( /* some data left */ ) {
            size_t const length = get_more_data(buffer, bufferSize, fh);
            if (XXH64_update(state, buffer, length) == XXH_ERROR) abort();
            // ...
        }
        // ...
    
        /* Produce the final hash value */
        XXH64_hash_t const hash = XXH64_digest(state);
    
        /* State could be re-used; but in this example, it is simply freed  */
        free(buffer);
        XXH64_freeState(state);
    
        return hash;
    }