Debugging Tools for Inspecting Turso's Bytecode and Execution Traces
Turso provides bytecode comparison utilities, EXPLAIN output inspection, trace logging via RUST_LOG, ThreadSanitizer stress tests, and deterministic simulation tools to debug its SQLite-compatible virtual machine.
Turso is an edge-ready SQLite-compatible database that compiles SQL into bytecode executed by a custom Virtual DataBase Engine (VDBE). Understanding how to leverage the debugging tools for inspecting Turso's bytecode and execution traces is essential for contributors and advanced users who need to verify query translation or diagnose runtime behavior.
Bytecode Inspection with EXPLAIN and Cross-Reference Validation
Turso generates SQLite-compatible bytecode that you can inspect before execution. The system provides two primary methods for validating this generation: manual inspection via the EXPLAIN command and automated comparison against reference SQLite output.
Ad-Hoc Query Analysis Using EXPLAIN
The simplest way to view the bytecode generated for any query is to prepend the statement with EXPLAIN. This outputs the virtual machine instructions that the VDBE will execute.
Run a query normally:
cargo run --bin tursodb :memory: 'SELECT * FROM foo;'
Then inspect its bytecode representation:
cargo run --bin tursodb :memory: 'EXPLAIN SELECT * FROM foo;'
This technique is implemented in the translator entry points found in core/translate/mod.rs, where the AST is converted into VDBE instructions.
Cross-Reference Debugging Against SQLite
To identify discrepancies in bytecode generation, compare Turso's output directly against the reference sqlite3 implementation. Discrepancies indicate potential bugs in Turso's translator or VM logic.
Generate bytecode from SQLite:
sqlite3 :memory: "EXPLAIN SELECT 1 + 1;"
Generate the equivalent from Turso:
cargo run --bin tursodb :memory: "EXPLAIN SELECT 1 + 1;"
Line-by-line differences between these outputs help isolate translation errors in the core/translate/* modules before they reach the execution engine in core/vdbe/execute.rs.
Execution Tracing and Runtime Logging
Once bytecode is generated, the VDBE executes it instruction by instruction. Turso provides fine-grained tracing capabilities to observe this execution flow in real time.
Enabling Trace Logs with RUST_LOG
The fastest way to observe the VM's step-by-step execution—including register moves, cursor operations, and instruction dispatches—is to enable trace-level logging using the RUST_LOG environment variable.
Run tests with full trace output:
RUST_LOG=turso_core=trace make test
Or trace a specific query execution:
RUST_LOG=turso_core=trace cargo run --bin tursodb :memory: 'SELECT …'
These trace logs originate from the VDBE implementation in core/vdbe/execute.rs and the instruction definitions in core/vdbe/insn.rs. The logging infrastructure hooks are defined in core/vdbe/mod.rs, which integrates with the tracing crate throughout the core library.
Concurrency Debugging and Stress Testing
Turso includes specialized tools for detecting race conditions and reproducing flaky failures that standard unit tests might miss.
ThreadSanitizer Stress Tests
To surface data races or use-after-free bugs invisible under normal execution, run the stress harness under ThreadSanitizer.
Install and configure the nightly toolchain:
rustup toolchain install nightly
rustup override set nightly
Execute the stress test with ThreadSanitizer enabled:
cargo run -Zbuild-std --target x86_64-unknown-linux-gnu \
-p turso_stress -- --vfs syscall --nr-threads 4 --nr-iterations 1000
The stress harness source is located at testing/stress/main.rs. This binary systematically exercises concurrent paths through the VDBE to expose threading issues.
Deterministic Simulation for Reproducible Bugs
When debugging non-deterministic failures, use the simulator binaries to replay execution with a fixed random seed, ensuring consistent reproduction of race conditions or timing-dependent bugs.
For single-threaded deterministic replay:
RUST_LOG=limbo_sim=debug cargo run --bin limbo_sim -- -s 12345
For multi-threaded concurrent simulation:
SEED=1234 ./testing/concurrent-simulator/bin/run
The simulator entry point resides at testing/simulator/main.rs. By fixing the seed, you can reliably reproduce the exact sequence of operations that triggered a failure, significantly reducing debug cycle time.
Key Source Files for Debugging
Understanding the architecture of Turso's execution engine helps map debugging observations to specific code locations:
core/translate/mod.rs— Entry point where SQL AST is converted into VDBE bytecode instructions.core/vdbe/execute.rs— The register-based VM interpreter that walks the bytecode program and executes each instruction.core/vdbe/insn.rs— Definitions and annotations for each SQLite-compatible opcode used by the VDBE.core/vdbe/mod.rs— Logging infrastructure and tracing hooks for the virtual machine.testing/stress/main.rs— Stress-test harness used with ThreadSanitizer to detect concurrency bugs.testing/simulator/main.rs— Deterministic simulation entry point for seeded failure reproduction.
Summary
- EXPLAIN command: Use
EXPLAIN SELECT ...withcargo run --bin tursodbto inspect generated bytecode for any query. - Bytecode comparison: Compare output between
sqlite3andtursodbto identify translation mismatches incore/translate/mod.rs. - Trace logging: Set
RUST_LOG=turso_core=traceto observe register moves, cursor operations, and instruction execution incore/vdbe/execute.rs. - Stress testing: Run ThreadSanitizer via
cargo run -Zbuild-stdon theturso_stresspackage to detect data races. - Deterministic simulation: Use
limbo_simwith fixed seeds or the concurrent simulator withSEEDenvironment variables to reproduce flaky bugs consistently.
Frequently Asked Questions
How do I compare Turso bytecode against SQLite to find translation bugs?
Run the same EXPLAIN query against both the reference sqlite3 binary and Turso's tursodb binary, then diff the outputs. Differences indicate potential issues in the translation layer located in core/translate/mod.rs or instruction implementation in core/vdbe/insn.rs.
What environment variable enables detailed execution traces in Turso?
Set RUST_LOG=turso_core=trace before running your command. This activates tracing in the VDBE core, emitting detailed logs from core/vdbe/execute.rs showing every register move and cursor operation during query execution.
How can I reproduce a flaky concurrency bug consistently in Turso?
Use the deterministic simulation tools with a fixed seed. Run cargo run --bin limbo_sim -- -s <seed> for single-threaded replay, or set SEED=<value> before executing the concurrent simulator. This ensures identical execution paths across runs.
Where is the VDBE interpreter implemented in the Turso source code?
The main bytecode interpreter loop resides in core/vdbe/execute.rs, which handles the register-based execution of SQLite-compatible opcodes defined in core/vdbe/insn.rs. The translation from SQL AST to these instructions originates in core/translate/mod.rs.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →