Docs · chapter 2

Recording

Updated 14 November 2026 · version 0.17

In short: ProtoTTD, Record, pick the program, use it, close it. The capture opens by itself and is kept in Documents\Protovision\runs. This chapter says what else you can do, and what exactly is recorded.

1

In the window

The front page has three tabs: Record a program from its start, Attach to one already running, Open a capture.

Record

The Record tab
Record: the program, its arguments and folder; Record, and Advanced settings beside it; the runs folder underneath.
  1. 1
    The program: its path (Browse…, or one recorded before from the list), its arguments, the folder it starts in.
  2. 2
    Advanced settings ▼ beside Record opens how it is recorded: start later, stop sooner, leave a library out, change an instruction, with templates. These are the keys of the config file, as fields; the window checks them as you type.
  3. 3
    Record. It starts at once. The window shows its output, the threads and the amount recorded live. Close the program, or press Stop: its capture opens in the same window.
Advanced settings: start, stop, keep, leave out, rules
Advanced settings: when recording starts and stops, libraries left out, rules, ready-made ones. The defaults record the whole run.

Attach

Pick a process in the list (or double-click it). Recording starts now, in every thread, until it exits or you stop it; the capture opens then. The same Advanced settings apply.

Open

Every run of the runs folder, newest first, with the ones opened from elsewhere. A capture that was opened once carries its index and opens in about a second, however big. Right-click a row for more.

The Open tab: the runs, their size, when they were recorded
Open: every run of the runs folder; indexed ones open in about a second.
The runs folder
Everything recorded goes to one folder, by default Documents\Protovision\runs: the window's runs, the agents' and the headless ones. The line under Record shows it: click it to open it, Change… to pick another (a large, fast disk), Default to go back. A name already used gets _2, _3… so nothing is overwritten.
2

From a terminal

The same recordings without a window: for scripts, servers and remote machines.

.\ProtoTTD.exe launch C:\tools\app.exe --input data.bin       # from its start
.\ProtoTTD.exe --config run.json launch app.exe                  # with a config file
.\ProtoTTD.exe attach 4312                                       # every thread of process 4312
.\ProtoTTD.exe attach 4312 7720                                  # one thread only
.\ProtoTTD.exe record app.exe                                    # the window, recording at once

While it runs, a line every few seconds gives the time, the threads, the speed and the megabytes written. When it ends, the last lines say how the program ended (its own exit, a crash and which, a stop) and where the capture is.

To…Do
Stop the program and keep its traceCtrl+C once: the trace is flushed, then packed. Or "stop_after" in the config.
Kill it at onceCtrl+C a second time.
Change where captures goThe window's runs folder, or the PROTO_RUNS_DIR environment variable for one run.
Record a 32-bit programNothing to do: the same commands, the 32-bit engine is used by itself.
3

What is recorded

Every instruction of every thread, with the registers and the memory it read and wrote, Windows' own code included.

The tracer runs the program instruction by instruction and writes down what each one did. Nothing is sampled and nothing is guessed: the debugger later shows the values the program really had. That covers your code, the libraries it loads, and Windows' own DLLs (ntdll, kernel32, KernelBase and the others): when the heap moves a block on realloc or an API fills a buffer, the copy is in the trace. Code generated at run time (a JIT, an unpacked payload) is recorded too.

What always runs natively

A few Windows functions run outside the tracer, call included, because the tracer must not be inside them: ending the process or a thread (ExitProcess, ExitThread, TerminateProcess, FreeLibraryAndExitThread), raising an exception and unwinding (RaiseException, RtlUnwindEx, RtlRestoreContext, NtContinue) and, in a 32-bit program, the gate its system calls go through. What they do is not in the trace; the program goes on recorded where they return or where the exception is handled. The kernel's side of a system call is never recorded: the bytes it writes appear when the program next reads them.

Leaving more out
"exclude_modules" in the config runs other libraries natively too: smaller captures, faster runs, for a library that only adds noise. The config file.
4

Speed and size

A recorded program runs several times slower than usual and writes gigabytes a minute.

On a desktop machine the tracer records a few hundred million instructions a second. A program that waits for you costs little; one that computes all the time feels slower. The capture grows with the work done: a short tool makes megabytes, a JavaScript engine running a test suite for a minute and a half made 20 GB. To keep it small:

  • start later with "trace_from" (a call, an address, a byte pattern), or stop sooner with "stop_after";
  • record only the threads that matter with a thread rule;
  • put the runs folder on a disk with room, and keep Windows Defender off it (Troubleshooting).