home / skills / tursodatabase / turso / debugging

debugging skill

/.claude/skills/debugging

This skill helps you debug tursodb by guiding bytecode comparison, logging, threading sanitizer, deterministic simulation, and corruption analysis.

npx playbooks add skill tursodatabase/turso --skill debugging

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
1.9 KB
---
name: debugging
description: How to debug tursodb using Bytecode comparison, logging, ThreadSanitizer, deterministic simulation, and corruption analysis tools
---
# Debugging Guide

## Bytecode Comparison Flow

Turso aims for SQLite compatibility. When behavior differs:

```
1. EXPLAIN query in sqlite3
2. EXPLAIN query in tursodb
3. Compare bytecode
   ├─ Different → bug in code generation
   └─ Same but results differ → bug in VM or storage layer
```

### Example

```bash
# SQLite
sqlite3 :memory: "EXPLAIN SELECT 1 + 1;"

# Turso
cargo run --bin tursodb :memory: "EXPLAIN SELECT 1 + 1;"
```

## Manual Query Inspection

```bash
cargo run --bin tursodb :memory: 'SELECT * FROM foo;'
cargo run --bin tursodb :memory: 'EXPLAIN SELECT * FROM foo;'
```

## Logging

```bash
# Trace core during tests
RUST_LOG=none,turso_core=trace make test

# Output goes to testing/test.log
# Warning: can be megabytes per test run
```

## Threading Issues

Use stress tests with ThreadSanitizer:

```bash
rustup toolchain install nightly
rustup override set nightly
cargo run -Zbuild-std --target x86_64-unknown-linux-gnu \
  -p turso_stress -- --vfs syscall --nr-threads 4 --nr-iterations 1000
```

## Deterministic Simulation

Reproduce bugs with seed. Note: simulator uses legacy "limbo" naming.

```bash
# Simulator
RUST_LOG=limbo_sim=debug cargo run --bin limbo_sim -- -s <seed>

# Whopper (concurrent DST)
SEED=1234 ./testing/concurrent-simulator/bin/run
```

## Architecture Reference

- **Parser** → AST from SQL strings
- **Code generator** → bytecode from AST
- **Virtual machine** → executes SQLite-compatible bytecode
- **Storage layer** → B-tree operations, paging

## Corruption Debugging

For WAL corruption and database integrity issues, use the corruption debug tools in [scripts](./scripts).

See [references/CORRUPTION-TOOLS.md](./references/CORRUPTION-TOOLS.md) for detailed usage.

Overview

This skill teaches practical techniques to debug tursodb by comparing SQLite bytecode, using detailed logging, stress-testing threading with ThreadSanitizer, running deterministic simulations, and applying corruption analysis tools. It focuses on isolating whether a difference is in parsing, code generation, the VM, or the storage layer. The goal is to provide repeatable steps to reproduce, inspect, and fix bugs in a Rust-based, SQLite-compatible embedded database.

How this skill works

Start by EXPLAIN-ing the same SQL in SQLite and tursodb and compare bytecode to determine whether the discrepancy arises in code generation or execution/storage. Use structured logging at the core and targeted modules to capture execution traces. For concurrency bugs, run stress tests under ThreadSanitizer and reproduce race conditions with a deterministic simulator using seeds. For corruption or WAL issues, use the dedicated corruption debugging tools to inspect pages and WAL contents.

When to use it

  • When query results differ between SQLite and tursodb and you need to locate the layer causing divergence
  • When intermittent crashes or corrupt databases appear after concurrent workloads
  • When a race condition or memory-safety issue is suspected
  • When you need a repeatable reproduction for a subtle bug
  • When validating fixes against SQLite behavior

Best practices

  • Always EXPLAIN the same SQL in both SQLite and tursodb first to classify the issue as codegen vs VM/storage
  • Enable targeted RUST_LOG traces rather than global trace to limit output size and focus on relevant components
  • Use ThreadSanitizer on a nightly Rust toolchain for concurrency stress tests to surface data races
  • Capture simulator seeds and test inputs to allow deterministic reproduction and easier bisecting
  • When investigating corruption, take read-only snapshots of files and run corruption tools rather than modifying production data

Example use cases

  • A SELECT returns different rows in tursodb than SQLite — use EXPLAIN to compare bytecode and trace VM execution
  • Intermittent assertion failures under load — run stress tests with ThreadSanitizer to find races
  • A database file fails integrity checks after a crash — run corruption analysis tools to locate damaged pages
  • Non-deterministic test failures — rerun the simulator with the recorded seed to reproduce the scenario
  • Performance regression suspected in code generation — compare generated bytecode sequences before and after changes

FAQ

What if bytecode is identical but results differ?

That indicates a bug in the virtual machine or storage layer; enable VM and storage logging and run targeted tests to isolate the fault.

How do I reproduce concurrency bugs reliably?

Use the deterministic simulator with a recorded seed and run ThreadSanitizer-backed stress tests to trigger and analyze races.