Here are a couple debugging tricks I stumbled upon out as I wrote the vector.


One time, I had a problem where something was reading a null pointer. I thought that after a swap, no thread could read the swapped in value, so I just swapped in a null pointer. Sadly, I was mistaken. Looking at the error message, which said pointer 0x0 is invalid to dereference, I got an idea. There were three places swapping in a null pointer; the first I changed to swap in 0x1, the second 0x2, and the third 0x3.

After running the program through Miri, I got the error message pointer 0x2 is invalid to dereference, and I knew where the bug was originating from.

unwrap vs. expect

Whenever you unwrap an Option or Result that is None or Err, Rust will print out a little diagnostic saying where the panic! happened. I found it helpful to use expect instead of unwrap because of the ability to provide some extra context.

For example, there is a method in the haphazard crate called AtomicPtr::load which returns an Option<&T>. It only returns a None value if the underlying AtomicPtr contains a null pointer. Instead of unwraping the return value of load, I called expect("read null pointer"). When I inevitably messed up and unwraped a None, I new there was a null pointer floating around because of the error message.

Although these tricks seem small, they actually saved me a lot of time.