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