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 ... with cargo run --bin tursodb to inspect generated bytecode for any query.
  • Bytecode comparison: Compare output between sqlite3 and tursodb to identify translation mismatches in core/translate/mod.rs.
  • Trace logging: Set RUST_LOG=turso_core=trace to observe register moves, cursor operations, and instruction execution in core/vdbe/execute.rs.
  • Stress testing: Run ThreadSanitizer via cargo run -Zbuild-std on the turso_stress package to detect data races.
  • Deterministic simulation: Use limbo_sim with fixed seeds or the concurrent simulator with SEED environment 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →