WoofWare.PawPrint
0.1.3
dotnet add package WoofWare.PawPrint --version 0.1.3
NuGet\Install-Package WoofWare.PawPrint -Version 0.1.3
<PackageReference Include="WoofWare.PawPrint" Version="0.1.3" />
<PackageVersion Include="WoofWare.PawPrint" Version="0.1.3" />
<PackageReference Include="WoofWare.PawPrint" />
paket add WoofWare.PawPrint --version 0.1.3
#r "nuget: WoofWare.PawPrint, 0.1.3"
#:package WoofWare.PawPrint@0.1.3
#addin nuget:?package=WoofWare.PawPrint&version=0.1.3
#tool nuget:?package=WoofWare.PawPrint&version=0.1.3
WoofWare.PawPrint
Slop status: original architecture is by me, with only reference assistance from LLMs. Then in 2026 I drove GPT-5.5 and Claude Opus 4.6/4.7 hard to get this to a usable state. Architecture is still mine, and I've read all the incoming non-test code, but have perhaps been a bit sloppy about some of it.
This is an unfinished deterministic implementation of a .NET runtime (specifically .NET 10). You give it a DLL, and it executes the entry point therein on an emulated runtime which controls all sources of nondeterminism.
Current status
Even incomplete as it is, PawPrint is currently capable of automatically detecting and reproducing a number of textbook race conditions, by running the input program with many different seeds for its source of randomness.
Nontrivial programs will probably fail loudly, unless you're lucky enough to be using only what I've already implemented.
The following work, at least in some minimal form:
Console.WriteLineasync void Main(string[] args) { ... }Task.Run- Quite a lot of reflection
- Many low-level synchronisation primitives like
Monitor
The following are specifically not implemented:
- GC and finalizers
Getting started
See the run-a-program.md doc for how to run a program, and fuzz-over-thread-scheduler.md for how to automatically detect concurrency-related bugs.
Goals
- Fully deterministic, ultimately to the point of supporting time-travel debugging and fuzzing over the order of thread execution. All sources of nondeterminism must be controllable by the PawPrint user somehow, such that emulating the same program twice from the same starting state always produces the same execution history.
- Fully managed. For example, I reimplement a large number of methods which are defined by P/Invoke, so that my deterministic runtime does not have to emulate native code.
- Fully in-memory except insofar as the program under test performs filesystem operations. (Filesystem operations are not yet supported, although the stderr/stdout file descriptors are.)
- No monkey-patching stuff out for convenience. IL interpretation is faithful. We emulate a rather eccentric JIT (the BCL relies on the presence of a JIT!), but if it's not a JIT intrinsic and it's not native code, we execute its genuine implementation.
Non-goals
- Performance. I expect this to be a very slow IL interpreter.
- Fidelity to the optimisations performed by e.g. RyuJIT or .NET's GC. I am purely interpreting IL (and mocking out native calls). For example, it is likely that I will simply never deallocate memory (so e.g. finalisers are not run).
- Support for any operating systems other than the ones on which I am running (currently macOS and Linux), and any fancy hardware features like SIMD.
Correctness
The project aims for correctness over availability, and will happily crash whenever it doesn't recognise some situation.
An advantage of a .NET runtime as a project is that it's unusually easy to test, because the CLR is a reference implementation. WoofWare.PawPrint has quite a lot of tests that "some C# code has the same observable result under PawPrint and the CLR", and a couple of F# tests too. (This makes me much happier about the rampant LLM usage than I would otherwise have been!)
Licence
MIT.
This project was produced with reference to the .NET runtime, which was used under the MIT licence. WoofWare.PawPrint may contain small amounts of that code.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- FSharp.Core (>= 10.1.203)
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.2)
- WoofWare.PawPrint.Domain (>= 0.1.3)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.