| # Debug Info |
| |
| Debug info is a collection of information generated by the compiler that allows debuggers to |
| correctly interpret the state of a program while it is running. That includes things like mapping |
| instruction addresses to lines of code in the source file, and type layout information so that |
| bytes in memory can be read and displayed in a meaningful way. |
| |
| Debug info can be a slightly overloaded term, covering all the layers between Rust MIR, and the |
| end-user seeing the output of their debugger onscreen. In brief, the stack from beginning to end is |
| as follows: |
| |
| 1. Rustc inspects the MIR and communicates the relevant source, symbol, and type information to LLVM |
| 2. LLVM translates this information into a target-specific debug info format during compilation |
| 3. A debugger reads and interprets the debug info, mapping source-lines and allowing the debugee's |
| variables in memory to be located and read with the correct layout |
| 4. Built-in debugger formatting and styling is applied to variables |
| 5. User-defined scripts are run, formatting and styling the variables further |
| 6. The debugger frontend displays the variable to the user, possibly through the means of additional |
| API layers (e.g. VSCode extension by way of the |
| [Debug Adapter Protocol](https://microsoft.github.io/debug-adapter-protocol/)) |
| |
| |
| > NOTE: This subsection of the dev guide is perhaps more detailed than necessary. It aims to collect |
| > a large amount of scattered information into one place and equip the reader with as firm a grasp of |
| > the entire debug stack as possible. |
| > |
| > If you are only interested in working on the visualizer |
| > scripts, the information in the [debugger-visualizers](./debugger-visualizers.md) and |
| > [testing](./testing.md) will suffice. If you need to make changes to Rust's debug node generation, |
| > please see [rust-codegen](./rust-codegen.md). All other sections are supplementary, but can be |
| > vital to understanding some of the compromises the visualizers or codegen need to make. It can |
| > also be valuable to know when a problem might be better solved in LLVM or the debugger itself. |
| |
| # DWARF |
| |
| The is the primary debug info format for `*-gnu` targets. It is typically bundled in with the |
| binary, but it [can be generated as a separate file](https://gcc.gnu.org/wiki/DebugFission). The |
| DWARF standard is available [here](https://dwarfstd.org/). |
| |
| > NOTE: To inspect DWARF debug info, [gimli](https://crates.io/crates/gimli) can be used |
| > programatically. If you prefer a GUI, the author recommends [DWEX](https://github.com/sevaa/dwex) |
| |
| # PDB/CodeView |
| |
| The primary debug info format for `*-msvc` targets. PDB is a proprietary container format created by |
| Microsoft that, unfortunately, |
| [has multiple meanings](https://docs.rs/ms-pdb/0.1.10/ms_pdb/taster/enum.Flavor.html). |
| We are concerned with ordinary PDB files, as Portable PDB is used mainly for .Net applications. PDB |
| files are separate from the compiled binary and use the `.pdb` extension. |
| |
| PDB files contain CodeView objects, equivalent to DWARF's tags. CodeView, the debugger that |
| consumed CodeView objects, was originally released in 1985. Its original intent was for C debugging, |
| and was later extended to support Visual C++. There are still minor alterations to the format to |
| support modern architectures and languages, but many of these changes are undocumented and/or |
| sparsely used. |
| |
| It is important to keep this context in mind when working with CodeView objects. Due to its origins, |
| the "feature-set" of these objects is very limited, and focused around the core features of C. It |
| does not have many of the convenience or features of modern DWARF standards. A fair number of |
| workarounds exist within the debug info stack to compensate for CodeView's shortcomings. |
| |
| Due to its proprietary nature, it is very difficult to find information about PDB and CodeView. Many |
| of the sources were made at vastly different times and contain incomplete or somewhat contradictory |
| information. As such this page will aim to collect as many sources as possible. |
| |
| * [CodeView 1.0 specification](./CodeView.pdf) |
| * LLVM |
| * [CodeView Overview](https://llvm.org/docs/SourceLevelDebugging.html#codeview-debug-info-format) |
| * [PDB Overview and technical details](https://llvm.org/docs/PDB/index.html) |
| * Microsoft |
| * [microsoft-pdb](https://github.com/microsoft/microsoft-pdb) - A C/C++ implementation of a PDB |
| reader. The implementation does not contain the full PDB or CodeView specification, but does |
| contain enough information for other PDB consumers to be written. At time of writing (Nov 2025), |
| this repo has been archived for several years. |
| * [pdb-rs](https://github.com/microsoft/pdb-rs/) - A Rust-based PDB reader and writer based on |
| other publicly-available information. Does not guarantee stability or spec compliance. Also |
| contains `pdbtool`, which can dump PDB files (`cargo install pdbtool`) |
| * [Debug Interface Access SDK](https://learn.microsoft.com/en-us/visualstudio/debugger/debug-interface-access/getting-started-debug-interface-access-sdk). |
| While it does not document the PDB format directly, details can be gleaned from the interface |
| itself. |
| |
| # Debuggers |
| |
| Rust supports 3 major debuggers: GDB, LLDB, and CDB. Each has its own set of requirements, |
| limitations, and quirks. This unfortunately creates a large surface area to account for. |
| |
| > NOTE: CDB is a proprietary debugger created by Microsoft. The underlying engine also powers |
| >WinDbg, KD, the Microsoft C/C++ extension for VSCode, and part of the Visual Studio Debugger. In |
| >these docs, it will be referred to as CDB for consistency |
| |
| While GDB and LLDB do offer facilities to natively support Rust's value layout, this isn't |
| completely necessary. Rust currently outputs debug info very similar to that of C++, allowing |
| debuggers without Rust support to work with a slightly degraded experience. More detail will be |
| included in later sections, but here is a quick reference for the capabilities of each debugger: |
| |
| | Debugger | Debug Info Format | Native Rust support | Expression Style | Visualizer Scripts | |
| | --- | --- | --- | --- | --- | |
| | GDB | DWARF | Full | Rust | Python | |
| | LLDB | DWARF and PDB | Partial | C/C++ | Python | |
| | CDB | PDB | None | C/C++ | Natvis | |
| |
| > IMPORTANT: CDB can be assumed to run only on Windows. No assumptions can be made about the OS |
| >running GDB or LLDB. |
| |
| ## Unsupported |
| |
| Below, are several unsupported debuggers that are of particular note due to their potential impact |
| in the future. |
| |
| * [Bugstalker](https://github.com/godzie44/BugStalker) is an x86-64 Linux debugger written in Rust, |
| specifically to debug Rust programs. While promising, it is still in early development. |
| * [RAD Debugger](https://github.com/EpicGamesExt/raddebugger) is a Windows-only GUI debugger. It has |
| a custom debug info format that PDB is translated into. The project also includes a linker that can |
| generate their new debug info format during the linking phase. |