Headcrab, a Rust debugger library

Hi all!

This month, we started a new project to create a modern, modular debugger library for Rust, Headcrab. Some of the high-level goals and reasons for starting from scratch were outlined in my blog post, "The Soul of a New Debugger", but here's a quick summary:

  • This project is intended to be a framework/library, as opposed to a full-blown debugger - at least, in the beginning. Focusing on providing the basic features would allow to use the library as a tool for a lot of debug-related purposes (including profiling, tracing, and use for education).
  • In the longer term, it will be integrated with the Rust compiler and the language servers. It will also provide a JSON-RPC API to integrate it with editors, IDEs, and GUI/browser-based tools (for visualization, code navigation, etc.)

At this time, the project is in the phase 1, the primary goal of which is to provide basic debugger functions to serve as building blocks for higher-level features. These basics include: symbolication (reading DWARF debug info from object files), reading & writing memory (cross-platform), setting breakpoints, reading & writing CPU registers, and handling events (signals, panics, etc.).

There's still a long journey ahead, but we've seen quite a good & steady progress already. We have published a July progress report, highlighting some of the changes made in this month.

We also welcome contributors, include those who are new to debuggers or Rust/systems programming, so please join in if you are interested!


Eek! Any chance you come up with a less gross name? Reminds to much of head lice and crabs. Eew..

1 Like

Sounds great though! I have been fighting with gdb so sounds pretty exciting to have a Rust specific debugger :smile:

1 Like

This is awesome - I can't wait to kick the tires on this.

1 Like

They might be gross but inspire a fearfull respect ^^.
Keep on the good work!


As I remember correctly there is crate for that.

That definitely wasn't the intention! :slight_smile: It's a tongue-in-cheek word play on the Rust's crab mascot (which is the opposite of gross, as I believe) & the critter from the Half-Life universe, which uhh... attaches itself to a host - and that's something we do with debuggers, too. You can find an attempt at our own mascot on the website.

Indeed, there are at least a couple of them: goblin and gimli. We use the latter.


My 10 cents: I think it's cool, and the mascot is cute.
And I really need a debugger.


Rust's crab mascot is fine. It's all about context and juxtaposition.

I'm old school, I have no idea what "half life" unless it's about radio active decay. "headcrab" just conjures up head lice and crabs in my mind. Grossness I'd rather be reminded of.

What you describe about the Half-Life critters makes them sound like Toxoplasma gondii https://www.discovermagazine.com/planet-earth/meet-the-parasites-that-control-human-brains. Even more gross!

Half Life is a game series, first game was released way back in 1998, that's pretty old school by now.

1 Like

I have heard of it.

The first and last computer game I bought was Starglider for my Atari ST 520. In 1987. https://en.wikipedia.org/wiki/Starglider

After many hours of tenaciously playing Starglider I hit it's maximum score of 100,000. At that point the game ended and it gave me a ranking of "Cheat".

I lost interest in games after that.


I see Headcrab is still making the buzz.

That name is genius!

I was wondering if you would have a syntax checker for imports in the toml file? I made a spelling error there and the compiler, very helpfully pointed me to faulty imports, but I did not understand that it was originated in the toml file.

Awesome project. The premise sounds really ambitious. Looking forward to where this project will go.
Love the name and the symbolism behind the name too :grinning:


Please file gdb bug reports for problems you find. There's a "rust" component there that you can use. Thanks.

The problem was that gdb was not codesigned. Could be solved by following those instructions until point 9, and then those instructions from 1.3 (since the drag to systems keychain did not produce a cert file on Desktop)

I am pretty sure many people reported that already, but if you want I can file a report :crayon: :email:

1 Like


Thanks for working this. The debugging experience in Rust could definitely be better.

You mention async in your blogpost. It's indeed really hard to debug deadlocks in tokio, for example, with GDB. Hope this will improve in the future :slight_smile:


Hi everyone,

This month has flown by already, and we have another project update!

To highlight just a few changes, here's what's been improved this month:

  • Source disassembly.
  • Stack unwinding.
  • Memory writing and reading functions.
  • Reading local variables.
  • Watchpoints on Linux.

You can find a full list of changes in the newsletter on our website, along with a demo for the command line example.


It is fantastic to hear your progress. I am waiting for your release. I love rust but I am not able to propose it as an alternative lang due to its debugger support. I use VSCode in windows and I have tried vscode-lldb and vsdbg. Out of these two, I felt the latter is better but not the best. Some points I hate with current debuggers,

  • Not able to visualise NDarray (shows just pointers)
  • Not able to set conditional breakpoint on Arc (because struct.read().field1 == 1 is not supported)
  • Not able to visualise slices
  • Most of the time, it is not detecting the breakpoint
  • Slowerdebug runtime (not compile time); When I run my code in debug mode it is excruciatingly slow by taking 5mins and the same on release build takes less than 1s. If I change the optimisation settings, variables are optimised out. Anyway, I don't think you will be able to do anything on this :frowning:
  • It is sad to see Rust community is happy with the current debugger and I don't see a roadmap. Maybe I am spoiled by C# debugger
1 Like

The problem here is that serious optimization involves significant code transformation, including assigning values to registers, potentially in a computationally-altered form, and moving loop-invariant subexpression computations out of loops and control-flow-invariant subexpressions out of if/then/else and match structures. Such optimizations do not leave artifacts that the debugger/programmer can directly relate to source program variables and expressions.