Motivation

Programming is difficult.

Our squishy human brains struggle to simulate what the computer will do when it runs our code. As a result we make lots of errors, many of them small, requiring us to divert our attention from the main problem we're working on to fix minor implementation details. This both takes up time and makes us lose focus on the high-level design.

The computer is going to run our code anyway, so why not do so immediately to check what it does?

Tool Overview

WhiteBox runs the code as it is written, capturing details about the execution. It can then give you live feedback about the run, showing you how variables change over time and other details.

This is intended to improve the developer experience by helping you to understand your code faster, and consequently:

  • catch and fix bugs earlier, before they cause major issues
  • iterate more often over your design, giving more opportunity for refinement

Tool Internals

WhiteBox is written in C and C++ with few external libraries:

  • Clang/LLVM is used for lazily JIT compiling code
  • Dear ImGui is used for creating the UI
  • A few single-header libraries are used for various utilities (STB, Mattias Gustavsson, Randy Gaul's cute_headers)

Just about everything else is written from scratch, including:

  • the hash table implementation
  • DWARF debug info parsing
  • plugins for code editors
  • ...

Project Details

WhiteBox has most of the initial set of features implemented and is nearly ready for alpha release.

Supported languages: C (and a small subset of C++) Supported platforms: Windows x64, Linux x64 (tested on Ubuntu 20.04) Supported code editors: 4coder, Emacs, Notepad++, Sublime Text, Vim/Neovim, Visual Studio, VSCode, (plus workarounds that should work for most other editors)

Support for more of each of these is planned or currently in-development.

Project Links

Recent Activity

&WhiteBox v0.122.0

New Features

  • Add simple watch expressions for the timeline, with feedback messages and underlines for parse errors
  • Add call stacks to timeline (including arguments & return values where captured)
  • Add text scaling (Ctrl + =/Ctrl + -)
  • Speed up data inspection, which bounds total running speed for user code
  • Add right-click options to timeline values to copy to clipboard
  • Visualize jumps in disassembly
  • Add AT&T/Intel disassembly syntax options
  • Add support for non-trivial copy constructors

Improvements & Fixes

  • Better handling for anonymous records
  • Improve font rendering with DirectWrite, FreeType, and TrueType backends
  • Improve C++ constructor handling
  • Show min/max values for timeline expressions
  • Improve data tree value graph
  • No longer break on Linux signals that are recommended to be ignored by default (e.g. SIGWINCH - change window size)
  • Animate the status bar colour when new messages are added to the console
  • Fix emacs plugin port issue
  • Fix misc issues; add resiliency to more edge-cases; reduce jank; ...

Known Issues

  • Globals that are mutated and not reset in user code are not always consistently reset between runs (e.g. changing functions back and forth with a locked caller). Saving your code or using Compiler > Reset (Ctrl+Shift+R) forces them to be reset.

Get access to the latest version here: https://azmr.itch.io/whitebox

N.B. If you were on the WhiteBox discord (https://chat.whitebox.systems) you'd have known about this last week 😁

New &WhiteBox feature: call stacks!

Each level shows the arguments that function was called with, and the return value if it was recorded.

They're currently aligned to the inspected function, but this is likely to change as we move toward inspecting multiple functions at once.

On request from a non-HMN user, I've just added a right-click option to &WhiteBox for copying values from the timeline.
This can then be fed back into the function caller to rerun, starting with the given value (for simple data, not pointer nests)...
(N.B. it copies the value with the current formatting, so to make it a valid C initializer Struct member names needs to be disabled)

@philliptrudeau has done some great work adding a DirectWrite backend for the text rendering in &WhiteBox: small text now looks much better!
(ideally viewed at 100%)

I spent some extra time on this at the end of last week getting &WhiteBox's disassembly jump lines to merge when they have the same destination.

I'm quite pleased with how much it improves the overall legibility of the potential jumps.

Can you spot the codegen oddity in the disassembly?

Thanks to some prompting from @megawolf, the jumps in &WhiteBox's disassembly view are now also coloured by direction

I just added the option to use Intel syntax (as well as AT&T) in &WhiteBox's disassembly, as well as arrows showing the destination of each jump (unconditional jumps are brighter than conditional jumps)

A user got &WhiteBox working with @raysan5's raylib, and I realised I hadn't tried it yet myself. This was something that needed correcting immediately!
It became possible with the concurrency features @philliptrudeau worked hard to get into v0.116.0

There are still things to hammer out from the previous interaction model (when to rerun the code, LOD, recording selection...)

But take a look:
live, graphed data & an instant edit-run loop for games!

raylib made this very easy:

  • download raylib-4.5.0_win64_msvc16.zip from https://github.com/raysan5/raylib/releases/latest
  • add -I[...]/raylib/include to the compiler flags
  • add [...]/raylib/lib/raylib.dll to the DLLs list
  • connect to WhiteBox from an example raylib file
  • start playing

We accidentally turned &WhiteBox into a graphing calculator 😄

&WhiteBox now has a pretty good heuristic for determining uninitialized values, which means we can show them as distinct and not include them in min/max stats: 🥳
e.g. k is uninit until line 8 finishes

&WhiteBox now has a pretty good heuristic for determining uninitialized values, which means we can show them as distinct and not include them in min/max stats: 🥳

&WhiteBox timeline data visualisation part 3: using de-emphasis for the "non-value" part of the bar instead of emphasis for "value" part itself. To me this reduces visual noise, but I'd like to hear thoughts from others. The value colour is what was the normal bar colour... it might be worth increasing the contrast somewhat.
Importantly, it also obscures the text less.
(Ignore the fact that [line] is coloured as it was previously, synthetic values need to be handled slightly differently)

&WhiteBox Noticed a bug in the previous image as I was writing about unit size: there's an off-by-"1" in max value for floats, which visually halves the 0.0-0.9 range shown.
This is now fixed:

&WhiteBox Noticed a bug in the previous image as I was writing about unit size: there's an off-by-"1" in max value, which visually halves the 0-1 range shown.
This is now fixed:

&WhiteBox timeline data visualisation part 2: lines for integral values have a height based on the span/range of values for that expression. This is particularly useful for expressions with small ranges like booleans!
This is meaningful because integers have a "unit size" of 1, but floats don't really have that. I could use "smallest non-zero exponent" or "smallest difference between values" or even "ordinal rank of all seen values (sorted)". The last of these would work for integers as well with large ranges but few values. It's better for distinguishing between values but not so good at making the actual value perceptually apparent.

&WhiteBox timeline data visualisation, part 1: horizontal lines indicating value for primitive types

&WhiteBox is prepping to go native, reading PDBs for arbitrary executables in place of the DWARF it generates internally.
Unsurprisingly, @NeGate has been doing a great job on this! 😄
Here's WhiteBox inspecting its own PDB functions, showing line info & local variables

&WhiteBox
https://twitter.com/whitebox_sys/status/1577053893150019584

I've been working my way through the ANSI control codes standard (+ extras) for WhiteBox's new in-built console.

We're capturing stdout & stderr from the user's process, reading ~all controls & handling more graphical ones than many terminals!

Can yours do curly red underlines?

&WhiteBox https://twitter.com/whitebox_sys/status/1573418093531271169

Just playing around with a WIP build of WhiteBox after @phillip_trudeau has made some upgrades.

I'm really enjoying taking advantage of this breakout, full-width timeline 😀

(thanks to @ocornut for Dear ImGui + docking + viewports!)

I added a red line to the end of the &WhiteBox timeline when a run had an error that prevented the function from returning.
I also fixed the status message telling you what line the error occurred on.
(There's a new release coming very, very soon!)

&WhiteBox now has a welcome screen with instructions on how to install the plugin for each editor, thanks to @BaremetalBaron

I'm really excited about this update to &WhiteBox - it adds the ability to call into other functions in your code (not just the function that's being recorded).
This means you can call main() (or something else that calls your function) and see how your function behaves with all of the parameters & extra context from runtime without having to input them manually.

It's now at a point where this seems to be working, it just needs to do a little tidying up after itself...

Reworked &WhiteBox's recording of the running process' memory to be faster, simpler, and to better capture pages changing protection/accessibility

I haven't shown much for &WhiteBox recently as it's all been pretty non-visual. Here's a little expression builder I made on stream for debugging expression evaluations.
It shows the value of that expression at a given sample of the run as well as a list of all the times the value changed during the run.

Having it as a builder means that I can enforce the validity of the expression, and it also means I don't have to handle shadowed variables with the same identifier as you would for text parsing. It's a little less clear how identities should be handled when taking a large span of time into account instead of just a single instant, so this lets me defer decisions about that.