XRayXL Armed Download

A flight recorder for the code running inside Excel.

When a spreadsheet is slow, freezes, or crashes, XRayXL tells you which XLL add-in and VBA functions actually ran — in what order, on which thread, triggered by which cell or button, with what arguments, returning what, how long each took, which functions threw errors and which handled them.

It changes nothing about your workbook: no cells touched, no macros added, no VBA source read. You arm it, recalculate or run your macros, then read what really happened — as a file, or on a timeline in your browser.

64-bit Excel on Windows One native DLL, no installer No .NET, no runtime GPL-3.0
One recalculation, as XRayXL recorded it

Four cells, in the order Excel calculated them rather than the order they sit on the sheet. A3 calls VbaOuter, which calls an add-in function through Application.Run; then A4, A2 and A1.

seqkindsourcemodulefunctioncallercallerrefargsretoutcometicks
1entryVBA[OneTimeline_8276.xlsm]ProbeVbaOutercell[OneTimeline_8276.xlsm]Sheet1!A3a1:Double=3
2entryXLLTracedAddin64.xllTxEcell[OneTimeline_8276.xlsm]Sheet1!A3a1:E=3
3exitXLLTracedAddin64.xllTxE3returned272
4exitVBA[OneTimeline_8276.xlsm]ProbeVbaOuter4returned4096
5entryXLLTracedAddin64.xllTxEcell[OneTimeline_8276.xlsm]Sheet1!A4a1:E=4.5
6exitXLLTracedAddin64.xllTxE4.5returned216
7entryVBA[OneTimeline_8276.xlsm]ProbeVbaPlaincell[OneTimeline_8276.xlsm]Sheet1!A2a1:Double=2
8exitVBA[OneTimeline_8276.xlsm]ProbeVbaPlain6returned410
9entryXLLTracedAddin64.xllTxEcell[OneTimeline_8276.xlsm]Sheet1!A1a1:E=1.5
10exitXLLTracedAddin64.xllTxE1.5returned167

Abridged for width. The file is a plain CSV of 23 columns, or JSON Lines if you ask for it, and also carries input, span, parent, depth, thread, qpc, proc, typetext, argcount, rettype, tracerticks and trust.

Read row 1 as: the VBA function VbaOuter, in module Probe of OneTimeline_8276.xlsm, called from Sheet1!A3, declared Double, given 3. The callerref is the same address Excel's own Range.Address(,,,True) gives — paste it straight back into a formula.

Row 4 closes it: returned 4 after 4096 ticks, 1151 of them the tracer's own (tracerticks), so the function itself took 2945.

What a row tells you
order

The real sequence

Every entry and exit in the order Excel actually ran them — not the order the sheet is laid out in, and not the order you assumed.

attribution

Who called it

The cell, button or event that started the chain, as a reference you can paste back into a formula. Multi-threaded recalculation is recorded per thread.

values

Arguments and returns

What went in and what came back, with their types — so a wrong answer leads to the call that produced it, not just the cell showing it.

duration

Cost per call

Ticks from a high-resolution counter on every exit, and how many of them were the tracer's own. Nested and recursive calls each carry their own, so the expensive one is the one that reads expensive.

structure

Depth and nesting

A per-thread shadow stack supplies depth and parent, so a flat file reconstructs into a call tree.

outcome

Errors, in full

Which procedure raised, which ones the error passed through, and which one finally caught it.

It follows XLL add-in and VBA code — macros, buttons and event handlers included — not Excel's own built-in functions, COM or RTD add-ins, or JavaScript custom functions.

The same trace, on a timeline

After Disarm, the Perfetto button opens the trace in Perfetto UI, an open-source trace viewer, in your browser. Each thread is a track, each call a slice nested under the call that made it, and Excel's events are markers. Click a slice for its arguments, its result, how long it took and how much of that was XRayXL's own.

Demo 10 after the show: a plasma painted across a canvas of cells, the countdown at 0, and the status line saying act 1 drew 4 frames and act 2 drew 287.
Demo 10: a plasma, painted two ways. The same VBA maths drawn twice, ten seconds each: act 1 makes one call to Excel per cell, act 2 one call for the whole canvas. Act 1 drew 4 frames; act 2 drew 287.
Demo 10's trace in Perfetto UI: StartShow over two RunAct slices, act 1's wide frames and act 2's thin ones, with part of act 1 selected and its calls summed by name below.
Its trace in Perfetto. With 1.75 seconds of act 1 selected, the pivot table sums it by name: 3,002 SetPixel calls took 1.5 seconds between them, and the colour maths inside them 72 milliseconds. The rest is Excel colouring cells.

The trace is converted on your machine, by a page that ships beside the add-in, so nothing is uploaded.

Before you run it

XRayXL hooks into Excel's internals. It patches a live Excel process, using details Microsoft can change in any update. It runs on 64-bit Excel only, antivirus and EDR may well notice it, and the trace file holds your workbook's data in the clear. Read the caveats before running it, especially on a machine someone else manages.

The docs — the same pages the download carries

Everything that comes with XRayXL, to read before you download anything.