Frontrun Documentation¶
Deterministic concurrency testing for Python.
Race conditions are hard to test because they depend on timing. A test that passes 95% of the time is worse than a test that always fails, because it breeds false confidence. Frontrun replaces timing-dependent thread interleaving with deterministic scheduling, so race conditions either always happen or never happen.
Four approaches, in order of decreasing interpretability:
DPOR — systematic exploration of every meaningfully different interleaving, with causal conflict analysis.
Bytecode exploration — random opcode-level schedules that often find races very efficiently, including races invisible to DPOR.
Marker schedule exploration — exhaustive exploration of all interleavings at the
# frontrun:marker level. Much smaller search space than bytecode exploration, with completeness guarantees.Trace markers — comment-based synchronization points for reproducing a known race window.
Contents:
- Installation
- Quick Start
- How Frontrun Works
- DPOR in Practice
- DPOR: Dynamic Partial Order Reduction
- Vector Clocks and Happens-Before
- Search Page
- Examples
- SQLAlchemy Lost-Update Race Condition
- SQL Conflict Detection – Technical Details
- How a SQL Statement Becomes a DPOR Conflict
- The Refinement Hierarchy
- Transaction Grouping
- Concrete Example: SELECT-then-UPDATE Lost Update
- Anomaly Classification
- PostgreSQL Isolation Levels
- Formal Verification with TLA+
- Why Not z3/SMT for Row-Level Conflicts
- Wire Protocol Parsing (C-Level Drivers)
- Indexical INSERT Resource IDs
- References
- Redis Conflict Detection – Technical Details
- Trace Filtering
- How It Works Under the Hood
- Python bytecode and the interleaving problem
sys.settrace: line-level and opcode-level tracingsys.setprofile: detecting C-level calls- Monkey-patching: cooperative primitives and I/O detection
LD_PRELOAD: C-level I/O interception- Putting the layers together
- What each layer can and cannot see
- Deadlock detection
- The DPOR algorithm in detail
- API Reference
- Frontrun Case Studies: Concurrency Bug Detection
Getting Started¶
The simplest entry point is trace markers — comment-based synchronization points that let you force a specific execution order:
from frontrun.common import Schedule, Step
from frontrun.trace_markers import TraceExecutor
class Counter:
def __init__(self):
self.value = 0
def increment(self):
temp = self.value # frontrun: read_value
temp += 1
self.value = temp # frontrun: write_value
def test_counter_lost_update():
counter = Counter()
schedule = Schedule([
Step("thread1", "read_value"),
Step("thread2", "read_value"),
Step("thread1", "write_value"),
Step("thread2", "write_value"),
])
executor = TraceExecutor(schedule)
executor.run("thread1", counter.increment)
executor.run("thread2", counter.increment)
executor.wait(timeout=5.0)
assert counter.value == 1 # One increment lost
For automatic race finding without manual markers, see DPOR in Practice (systematic) or How Frontrun Works (random bytecode exploration).
Indices and Tables¶
search