Rust development using VS Code on OS X, debugging included.

Disclaimer: this was tested on OS X El Capitan 10.11.4 but most of it should work unchanged in other platforms. Also, I’m sure there’s room for improvement especially regarding the debugger setup. If there’s a better way please let me know and I’ll update this document accordingly.

Getting Started

Make sure you have a recent version of Rust (1.8 or later). You will also need Rust’s source code somewhere on your computer and if you haven’t installed Racer now’s a good time to do it:

cargo install racer

Open Visual Studio Code and install the Rusty Code extension. If you haven’t used VS Code before here’s a quick-start.

As usual, VS Code will need to restart itself after the extension is installed.

After VS Code restarts, we need to configure Rusty Code. You can configure it in User Settings or in Workspace Settings. I’ll use the former:

In this file (settings.json) you need to specify the path to the racer and cargo binaries if they are not on your PATH. In my system only cargo is on my PATH so I had to specify the path to racer. Additionally you need to specify the path to rust’s source code:

There are several other settings you can specify, refer to Rusty Code’s documentation for more information.

Editing, Building and Running

At this point Racer should be On and autocompletion should be working:

You should be able to build and run your project using the command palette:

Debugging (Part I: Basic Setup)

You will need to install the Debug extension:

This extension supports both GDB and LLDB but in reality LLDB is only supported via LLDB-MI and I haven’t found a way to use Rust’s pretty printers with it. There’s nothing wrong with GDB but if you use a Mac you need to install it yourself since Apple dropped GDB in favor of the LLDB debugger a while ago. I wrote a little guide to help you with the process.

With GDB installed and on your PATH, you can configure the debugger for this project, click on the fourth symbol on the left (the one that looks like a bug) and then click the green triangle (or alternatively the wrench with the red dot) to bring the following menu:

Select GDB and change the target path to your debug binary, in our case it’s target/debug/hello_world:

You can now debug your program, you can set breakpoints (clicking at the left-most part of a line) and inspect your variables. If you have leftover output from the build process and you’re not seeing the output of your program, you need to click the Debug Console icon:

You can read more about debugging in VS Code right here.

Debugging (Part II: Pretty Printing)

What you’re missing at this point is pretty-printing. Some of your variables will look pretty bad on mouse-overs:

If you had to install GDB manually, you’re probably missing Rust’s python files required for pretty printing with GDB. You need to copy and from [rust sources]/src/etc/ to /usr/local/lib/rustlib/etc/ (assuming Rust was installed to /usr/local/bin).

Then you need to create a file called .gdbinit in your home folder with the following contents (assuming again that Rust was installed to /usr/local/bin):

print “ — — Loading Rust pretty-printers — — “
sys.path.insert(0, “/usr/local/lib/rustlib/etc”)
import gdb_rust_pretty_printing

And voilà, you should see a message saying it’s loading the pretty printers in the debug output and the mouse-over should display a prettier value for your variables:

Debugging (Part III: Alternative Setups)

This section is included for information purposes only. It does’t include any actual setup instructions.

As I mentioned before, LLDB is also supported via LLDB-MI. That said I couldn’t get the pretty printers to work. The Debug extension for VS Code uses the data-evaluate-expression command to display the variables andfor some reason LLDB-MI doesn’t use the pretty printers for that specific command (at least under OS X).

Also, as an alternative to the .gdbinit file, rust provides a rust-gdb shell script that can be used instead of gdb. This script configures pretty printing and launches then gdb. You would have to specify a “gdbpath” entry in your launch.json file pointing to rust-gdb. With that said, I couldn’t get it to work with my current setup and had to rely on .gdbinit.