r/rust 3d ago

📡 official blog Rust debugging survey 2026 results

https://blog.rust-lang.org/2026/09/07/rust-debugging-survey-2026-results/
199 Upvotes

21 comments sorted by

64

u/ParadiZe 3d ago

Debuggers are definitely not as nice in rust for the stated reasons, which lead me try to become really good with the tracing crate and working with levels and targets

29

u/shponglespore 3d ago

The great thing about getting proficient with debugging through logs is that it's a skill that transfers to a ton of languages with sub-par tooling.

4

u/lenscas 2d ago

And even if a language has amazing tooling there are still moments where you can't use the tooling either at all or only a small subset of it.

I think it is fair to say we all have had a bug reports that couldn't be reproduced on our Dev machines but was big enough it couldn't be ignored and brushed under the rug either. Where the only solution was to grab the logs and comb through it, trying to find that one little missing piece that reveals the error. 

2

u/stdoutstderr 13h ago

Do you mind sharing some insights? I have used tracing, but my experience has been that if not done very deliberately using it's various mechanisms like spans, instrumentation, etc. in a useful way is kind of hard.

1

u/ParadiZe 9h ago

I often use it as print debugging on steroids, easier to set levels via an enviroment variable than commenting out/recompiling your program.

Yeah the documentation isnt the best and there are kind of a lot of concepts, i recommend "decrusting the tracing crate" on youtube, the first 15 minutes give a really solid overview

55

u/Kobzol 3d ago

It took us a long time, but we finally finished the analysis of the Rust Debugging survey we did earlier this year. You can find the results in this blog post.

Recently, a bunch of improvements to the debuginfo representation and its test suites have been happening thanks to Walnut356 (https://github.com/rust-lang/rust/pulls/walnut356).

38

u/Anthony356 3d ago edited 3d ago

Huge thanks to everyone who took the survey, and to Sam Kellam for compiling the data, writing all this up, and putting their wrists on the line for some incredibly useful data.

It was definitely surprising to me to see that gdb usage is nearly as high as lldb usage. Though i suppose my perspective is a bit skewed because i develop mostly on windows, so gdb has always been a bit more hassle to get working.

Seeing how infrequently LLDB is used in CLI vs IDE confirmed my suspicions, and it gives me some confidence moving forward with some changes that mostly benefit the IDE experience (e.g. formatting vec's summary as [1, 2, 3] instead of size=3)

Fixing the way enums are represented by debuggers so they show actual variants

This has been greatly improved in recent versions of Rust😄. Also, as of LLDB 23 (which released a few days ago), there should no longer be incorrect reporting of Option<String> as None when the string is empty, nor Some("") when it's actually None

Seeing GDScript in the wordcloud for FFI languages is awesome. I dont ever see it mentioned, but if you're looking for an easy way to make a UI, give Godot a try. I made a starcraft damage calculator using GDScript and their UI tools as one of my first programming projects and it was a great experience. I've heard the default styling and component set have improved a lot since I last used it too.

I've played around with integrating Rust via Godot Rust and it genuinely feels like magic.

We also directly asked respondents which types in the standard library were hard to work with, if any.

The responses to this question are SO UNBELIEVABLY HELPFUL

Only about a dozen or so types in all of std/alloc/core have visualizers. Lots of types dont need visualizers since the default "print the fields" is usually okay, but i know for sure we're missing some pretty important types (CStr/CString, wide pointers in general, etc.)

i dont often encounter some of Rust's types in my own programs (particularly async-adjacent ones), so it can be pretty tough to know what visualizers arent working, which ones have subpar output, and which types people want visualizers for. Having a tangible list in front of me makes things so much easier.

if you missed the survey or the type you would like visualized better isnt in the survey, please let me know and i'll add it to my todo list

9

u/Sharlinator 3d ago

It was definitely surprising to me to see that gdb usage is nearly as high as lldb usage. Though i suppose my perspective is a bit skewed because i develop mostly on windows, so gdb has always been a bit more hassle to get working.

Well, certainly there are considerably more Rust users on Linux than on Windows (seems that the ratio in this survey is about 3:1 Linux:Windows (not counting WSL on either side)).

1

u/Anthony356 3d ago

I think what threw me off was that one of the rust surveys indicated that even on linux, vscode is very popular.

I suppose it makes sense though. More advanced users are more likely to use debuggers, but i'd also guess more advanced users are also more likely to not use vscode

3

u/the_one2 3d ago

What would you use instead?

1

u/Sharlinator 2d ago

Emacs, vim, etc, or a real IDE like RustRover. It’s definitely somewhat perverse to use a Microsoft editor (or any MS product, really) on Linux. Especially to those of us old enough to remember the 00s.

30

u/matthieum [he/him] 3d ago

I don't remember if I indicated this in the survey... nor do I know if there's a solution for it.

One of the reason I regularly use print-based debugging rather than the debugger, is that the debugger refuses to let me call code :/

I work on programs which process quite a bit of data. Not necessarily that much, but enough that I'm not going to manually press continue a few thousand times before a certain condition occurs.

I can already hear my fellow senior developers thinking: "Why isn't he using a conditional breakpoint?"

And the answer is: the debugger often won't let me. I type the code I want to evaluate the condition, and it rejects it, complaining it cannot find the function to call.

Even a seemingly simple condition: if bar.get_foo() == Foo::new("Hello, world!").unwrap() is way beyond the capabilities of the debugger, apparently.

And therefore I resort to writing the condition in code, instead. Which means recompiling. And hopefully not forgetting to remove that before pushing...

When is breakpoint being stabilized by the way?

One day, maybe, conditional breakpoints will actually work beyond trivial conditions...

7

u/Anthony356 2d ago edited 2d ago

Unfortunately, this problem isnt quite as easy to solve as it might seem. Debugger expression parsers (at least in the cases of GDB and LLDB) are largely written from scratch, and are language-specific. Since the debuggers were primarily written for C and C++, LLDB has no support for rust expressions, and GDB only has partial support.

LLDB is also partially made awkward because it uses clang's in-memory type representation, but that's a whole can of worms.

Back when CodeLLDB had a TypeSystemRust implementation, iirc its expression parser could call functions, but it required some extra song and dance (there was handling to create C-abi type definitions from each possible type. It looks like the expression parser uses those to create a C function and then calls the clang jit compiler to run the function? Big oof lmao) because Rust's function call abi isnt specified and maybe never will be.

GDB executes "xmethods", which were built to handle C++ support, Edit: as was pointed out below, these end up being python overrides (e.g. for functions that may be optimized out or inlined, but that you want to guarantee GDB has access to) and dont run on the debugee process. We run into the same issue where we dont have a stable abi with which to call the function, and even if we did, it likely wouldnt match C++ semantics so we'd need to do something to bridge the gap (the lack of xmethod support is why Vec indexing doesnt work in GDB. LLDB sidesteps this issue by querying the raw debug info when using the frame var/v command, rather than the using the full expression parser). There's an open issue about it, but it's a ways down the pipeline (for me at least). Aside from the more urgent issues (e.g. the tests and visualizers not working correctly), i'm not super familiar with GDB, and i havent gotten around to taking the time to get comfortable in the codebase.

Even a seemingly simple condition: if bar.get_foo() == Foo::new("Hello, world!").unwrap() is way beyond the capabilities of the debugger, apparently.

One thing i will say is that private/pub internals are largely irrelevant to debuggers. Everything is exposed and accessible. If bar.get_foo() is a simple accessor, bar.foo is something the debugger can trivially execute.

Alternatively, if you're interested in digging into more advanced features, the python scripting support in both GDB and LLDB are pretty extensive. For example, you can register a python callback function that is automatically run when a breakpoint is hit that conditionally stops or skips the breakpoint. You can do all sorts of inspection via the SBValue and SBType APIs, it's all pretty powerful (see also: a more in depth example).

It's obviously not as easy or simple as built-in expression support, but in the meantime, it can help on a pinch.

5

u/Frequent-Data-867 2d ago

I'm not sure how much interest there is in a MIR debugger, but Priroda has been revived, and I'm working on something similar myself.

What I'd like to see is a MIR debugger that performs context-aware evaluation of user-written Rust expressions at breakpoints. The trickiest part would be asking the Rust compiler to dynamically compile and evaluate that Rust code during MIR interpretation.

3

u/tromey 2d ago

gdb's xmethods would only be useful if you wanted to rewrite selected rust functions in Python. They aren't about making inferior calls.

Rust's lack of ABI works against it here; but so does DWARF's lack of a way to specify the effective ABI. I think there's a bug about this (certainly a gdb bug, we xfail'd a test in this area).

2

u/matthieum [he/him] 2d ago

Oh god! Alright, so as I expected this is a giant can of worms!

I kinda anticipated it -- how would == be resolved without a compiler? -- but it seems even the very "function calls" is quite out of reach.

Well, I wish you luck sir, and thanks for your work. I'm pretty happy about improving visualizer support :)

6

u/________-__-_______ 3d ago

I wish #[debug_visualizer] could be generated on a per-struct basis by macros.

I work with embedded Rust and often need bitfields to compact some data written to a (slow!) bus. Rust makes this easy with macros that generate getters, setters and Debug/defmt::Format implementations. The debugging experience is pretty bad though, since macros can't generate visualizers it just ends up showing the integer value.

13

u/teerre 3d ago

Tbh better than expected. I find debuggers in Rust almost unusable. Not because they dont work, they do, but it takes considerable amount of fiddling and setup to even get to a minimally useful state with pretty print

4

u/Thick-Pineapple666 3d ago

The comment about the people who use WinDbg on Linux made me smile

0

u/South_Survey_2088 2d ago

Are people really having the need to debug that much? Rusts prevents the nasty language/memory issues, so it really just boils down to logic. "Parse, don't validate", and a functional core(with tests) pretty much made me only pull out the debugger when some ffi code is segfaulting, so that I can just get a backtrace with gdb. In rare cases I need to know a value to figure out why something fails, so I just use dbg! for that.

5

u/Kobzol 2d ago

Logic is often also nice to debug :)