1 unstable release

Uses old Rust 2015

0.1.0 Aug 3, 2015

#29 in #asm

BSD-3-Clause

7KB
81 lines

breakpoint!()

Build Status

Usage

Add to Cargo.toml:

[dependencies]
breakpoint = "0.1.0"

Import the macro into your crate:

#![feature(asm)]
#[macro_use] extern crate breakpoint;

Set breakpoints!

breakpoint!();

Set breakpoints with conditions!

breakpoint!(ref_count == 1);

Documentation

Read the docs!


lib.rs:

Set breakpoints from within the comfort of your editor.

Usage

Import the macros from the breakpoint crate. Unfortunately, the breakpoint!() macro relies on the asm!() macro, so we need #![feature(asm)] as well.

#![feature(asm)]
#[macro_use] extern crate breakpoint;

Then, anywhere you would like to pause at in your debugger, add the following line:

// Always pause.
breakpoint!();

// Only pause if `condition` is true.
breakpoint!(condition);

Example

Imagine we have this really tricky function that needs to be debugged, because we are seeing integer underflows:

fn tricky_function_must_be_debugged(val: usize) -> usize {
    val - 1
}

We can set a breakpoint in the program from the comfort of our editor, rebuild, and run under a debugger to see where things are going wrong:


fn tricky_function_must_be_debugged(val: usize) -> usize {
    // Set a breakpoint before the underflow, so we can debug!
    breakpoint!();
    val - 1
}

If the problematic function is only called a handful of times, congrats! You've uncovered the root cause of the bug by now!

If, however, the tricky function is called many times, and the bug only manifests after many calls, it is useful to break only if some condition evaluates to true:


fn tricky_function_must_be_debugged(val: usize) -> usize {
    // Only break if we are going to underflow!
    breakpoint!(val == 0);
    val - 1
}

Why?

It can be convenient. Especially when you're already in your editor, you can't remember your debugger's incantation for conditional breakpoints (often made worse by poor support for parsing Rust expressions in current versions of debuggers), and/or your crate isn't super big so rebuilding is fast.

In particular, I got annoyed that panics from failing tests didn't automatically pause my debugger, and could never remember the incantation for breaking on panic off the top of my head. I find this easier than that, most of the time.

Admittedly, breakpoint!() is far from perfect. These things tend to work better in dynamic languages where re-evaluating a function is super easy and doesn't need a full recompilation.

No runtime deps