---
description: Debug Solidity contracts with Forge traces and the interactive debugger.
---

## Debugging

Forge provides detailed traces and an interactive debugger to understand contract execution.

### Traces

Run tests with `-vvvv` to see full execution traces:

:::terminal
```bash
$ forge test -vvvv
```

```ansi
// [!include ~/snippets/output/cheatcodes/forge-test-vvvv:output]
```
:::

The trace shows every call, its inputs, outputs, and gas usage.

### Understanding trace output

Each line shows:
- **Gas used** in brackets
- **Contract::function** being called
- **Call type** (staticcall, delegatecall, etc.)
- **Return value** or revert reason

Indentation indicates call depth.

### Tracing a failed transaction

Debug a transaction that failed on-chain:

```bash
$ cast run 0x<txhash> --rpc-url $RPC_URL
```

This replays the transaction and shows the execution trace. Add `--debug` to open the transaction in the interactive debugger instead; `cast call --trace --debug` does the same for a call without sending it.

### Interactive debugger

Launch the debugger for a single test:

```bash
$ forge test --debug --match-test test_Increment
```

In an interactive terminal, a filter that matches more than one test opens a prompt asking which test to debug, so you can also run `forge test --debug` without a filter and pick from the list. In a non-interactive terminal the filter must match exactly one test.

The debugger is a terminal UI with five panes:

- **Source** – Source code with the currently executing line highlighted.
- **Opcodes** – The opcode list for the current call, with the program counter, address, and gas information in the title.
- **Variables** – Parameters, return values, and locals in the current scope, with decoded values where available. When you step through a constructor during contract creation, the constructor arguments are decoded and shown here. Storage reads and writes performed by the current step also appear in this pane.
- **Stack** – The current EVM stack.
- **Data** – A shared pane showing either a buffer (memory, calldata, or returndata) or the [storage explorer](#storage-explorer).

The debugger picks a two-column or single-column layout based on the terminal size. Press `l` to switch layouts, or force one with `--debug-layout <horizontal|vertical>`.

#### Key bindings

| Key | Action |
|-----|--------|
| `j` / `k` (or arrow keys, mouse scroll) | Step forward / backward one instruction |
| `s` / `a` | Move to the next / previous jump |
| `C` / `c` | Move to the next / previous call |
| `g` / `G` | Go to the beginning / end |
| `'<char>` | Jump to the breakpoint set with [`vm.breakpoint`](/reference/cheatcodes/breakpoint) |
| `0-9` | Repeat prefix for movement keys, e.g. `10k` steps back 10 instructions |
| `b` | Cycle the data pane between memory, calldata, and returndata |
| `J` / `K` | Scroll the stack pane |
| `Ctrl+j` / `Ctrl+k` | Scroll the data pane |
| `t` | Toggle stack labels |
| `m` | Toggle UTF-8 decoding of the active buffer |
| `p` | Go to a program counter |
| `o` | Go to a byte offset in the active buffer, or to a slot when the storage explorer is active |
| `/`, then `n` / `N` | Search opcodes in the current call, then repeat the search forward / backward |
| `:` | Open the command prompt |
| `h` | Toggle the shortcut footer |
| `q` | Quit |

#### Command prompt

Press `:` to run a debugger command. `:help` lists all commands and their aliases.

| Command | Action |
|---------|--------|
| `:pc <pc>` (alias `:continue <pc>`) | Jump to a program counter in the current contract |
| `:line <line>` | Jump to the nearest instruction mapped to a source line in the current contract |
| `:mem [<offset>]`, `:calldata [<offset>]`, `:ret [<offset>]` | Select a buffer in the data pane, optionally jumping to a byte offset |
| `:storage [<slot>]` | Open the storage explorer, optionally jumping to the nearest access of a slot |
| `:transient [<slot>]` | Open the transient storage explorer, optionally jumping to a slot |
| `:source`, `:opcodes`, `:variables`, `:stack`, `:data` | Show or hide a pane; the remaining panes reclaim the space |

#### Storage explorer

`:storage` switches the data pane to a storage view that lists every slot the current call has accessed up to the current step, showing each slot's most recent operation (`SLOAD` or `SSTORE`) and value. The slot touched by the current step is highlighted. `:storage <slot>` jumps to the nearest access of a specific slot: the access at or after the current step, or the most recent earlier one.

`:transient` and `:transient <slot>` provide the same view for transient storage (`TLOAD` and `TSTORE`). Press `b` to switch the data pane back to the buffer view.

#### Breakpoints

Place breakpoints in code with the [`vm.breakpoint`](/reference/cheatcodes/breakpoint) cheatcode:

```solidity
vm.breakpoint("a");
```

Pressing `'a` in the debugger jumps to the step where the breakpoint was recorded.

### Debugging scripts

Debug a script:

```bash
$ forge script script/Deploy.s.sol --debug
```

### Console logging

Add logs to your contracts for debugging:

```solidity
import {console} from "forge-std/console.sol";

function transfer(address to, uint256 amount) public {
    console.log("Transfer from:", msg.sender);
    console.log("Transfer to:", to);
    console.log("Amount:", amount);
    // ...
}
```

View logs with `-vv` or higher:

```bash
$ forge test -vv
```

For structured output, Foundry also supports `console.table`, which can make repeated values easier to scan than a long sequence of `console.log` lines.

### Labeling addresses

Make traces more readable by labeling addresses:

```solidity
function setUp() public {
    alice = makeAddr("alice");
    bob = makeAddr("bob");
    
    vm.label(address(token), "Token");
    vm.label(address(pool), "Pool");
}
```

Traces will show `Token::transfer()` instead of `0x1234...::transfer()`.

### Stack traces

When a test fails, use `-vvv` to see a stack trace showing exactly where the revert occurred:

:::terminal
```bash
$ forge test -vvv
```

```ansi
// [!include ~/snippets/output/cheatcodes/forge-test-fail-vvv:output]
```
:::

The trace shows the call hierarchy with the revert bubbling up, and the **Backtrace** pinpoints the exact location in your code.

### Inspecting inheritance linearization

When debugging overrides in a multiple-inheritance hierarchy, inspect the method-resolution order directly:

```bash
$ forge inspect src/MyContract.sol:MyContract linearization
```

This shows the order Solidity uses to resolve inherited functions, which is often the fastest way to understand why a particular override or `super` call is being selected.
