| # 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. |
| |
| * [TIS PE specification](https://web.archive.org/web/20260315080740/http://x-ways.net/winhex/kb/ff/PE_EXE.pdf) |
| which includes a lengthy section titled "Microsoft Symbol and Type Information", detailing much of |
| the CodeView format. |
| The document was created in 1993, but the information is still detailed, |
| accurate, and has useful diagrams. |
| * 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. |
| * [PDB-Documentation](https://github.com/PascalBeyer/PDB-Documentation) - a resource compiling |
| much of the publicly available information about PDB and CodeView. |
| |
| # 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. |