> ## Documentation Index
> Fetch the complete documentation index at: https://developers.stellar.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Debugging Modes

> Debug smart contracts natively and as WASM.

Soroban contracts are as much as possible regular Rust programs and can be debugged using the same tools you'd usually use.

The debugging facilities available differ significantly depending on whether a contract is compiled natively for local testing, or compiled into Wasm for deployment.

Deciding between these two modes and making the most of them while debugging requires a **careful understanding** of which code is compiled-in to deployed contracts and which code is only available for local testing.

## Local-testing mode

It is possible (and encouraged during development) to compile Soroban contracts **natively** (eg. as x86-64 or AArch64 code) and link against the host environment **directly**, such that the contract is not a guest running in a Wasm virtual machine at all: it is simply one native library calling another -- its host -- and both host and contract are linked together as a single program, together with a test harness.

This configuration is referred to as **"local-testing mode"** and since it eliminates the Wasm virtual machine from the debugging experience it has many advantages:

* Tests run much faster since there is no VM interpreting them, and will execute in parallel by default on multiple threads.
* Tests can use numerous standard testing and debugging techniques:
  * [The standard Rust `#[test]` harness](https://doc.rust-lang.org/reference/attributes/testing.html), including push-button IDE support for running and re-running single tests.
  * [Standard IDE-supported debuggers](https://code.visualstudio.com/docs/languages/rust#_debugging), including IDE support for setting breakpoints and inspecting values in both contract and host.
  * Lightweight debugging via [standard logging](https://docs.rs/log/latest/log) or [tracing](https://docs.rs/tracing/latest/tracing).
  * Systematic testing such as [fuzzing](https://crates.io/crates/cargo-fuzz), [property-testing](https://crates.io/crates/proptest), or even [model checking](https://crates.io/crates/kani-verifier) or [formal verification](https://github.com/xldenis/creusot).
  * The simplest of all debugging approaches, [printing to standard error](https://doc.rust-lang.org/std/macro.eprintln.html).

Local-testing mode is the **default** configuration when compiling code targeting your local computer's CPU and operating system, which is what cargo will do if you set up a new Rust project and don't specify a target.

## Wasm mode

If on the other hand you wish to compile for deployment, you must tell cargo to build for the Wasm target.

Building for Wasm will *disable* many of the debugging facilities described above, typically for one of three reasons:

* The Wasm VM simply can't (or the VM we've chosen doesn't) provide them.
* The Wasm VM *could* provide them but doing so would violate constraints of the [contract Rust dialect](https://developers.stellar.org/docs/learn/fundamentals/contract-development/rust-dialect.md).
* The Wasm VM *could* provide them but doing so would make the resulting Wasm code impractically large.

While we encourage most testing to happen in local-testing mode, some problems will obviously only arise in deployment and some debugging facilities thus remain available even there:

* A "sandbox" host with a mock-ledger that can read and write `CONTRACT_DATA` ledger entries to the local filesystem.
* A general logging system that allows contracts to log values of the [shared host/guest "value" type](https://developers.stellar.org/docs/learn/fundamentals/contract-development/environment-concepts.md), even in production.
* User-extensible `Error` codes that can be returned from any contract call to indicate problems.
