Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(debugger): Docs #4145

Merged
merged 27 commits into from
Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
2015d62
first stub
mverzilli Jan 23, 2024
4d940cb
Update debugging_with_the_repl.md
mverzilli Jan 23, 2024
848f206
Update debugging_with_the_repl.md
mverzilli Jan 23, 2024
c9b86e7
Initial drafts for missing parts
mverzilli Jan 24, 2024
6a5dea3
Polish quickstart doc
mverzilli Jan 24, 2024
fd7773b
Fix debugger doc folders casing
mverzilli Jan 24, 2024
e042a2b
Fix debugger how to category
mverzilli Jan 24, 2024
c1a8b33
Polish VS Code reference
mverzilli Jan 24, 2024
123d799
Polish repl how to
mverzilli Jan 24, 2024
bffcd34
Polished vscode reference
mverzilli Jan 24, 2024
eabc04f
Polish REPL reference
mverzilli Jan 24, 2024
3fbba2b
Polish known limitations
mverzilli Jan 24, 2024
e6311be
Replace Brillig with unconstrained lingo
mverzilli Jan 25, 2024
3127a89
Use admonitions for notes
mverzilli Jan 25, 2024
d7f23d9
Remove quickstart from debugger intro
mverzilli Jan 25, 2024
0ae76d8
Move tooling to root level
mverzilli Jan 25, 2024
338b269
Remove references to Brillig
mverzilli Mar 13, 2024
1ca9c3a
Merge branch 'master' into chore/debugger-docs
mverzilli Mar 13, 2024
51cf8f6
Remove minimum versions for release
mverzilli Mar 15, 2024
d35e25f
Merge branch 'master' into chore/debugger-docs
mverzilli Mar 15, 2024
abd4641
Merge branch 'master' into chore/debugger-docs
mverzilli Mar 18, 2024
daa3f68
Revert accidental manual change on versioned docs
mverzilli Mar 18, 2024
73a4cb1
Add missing line at eof
mverzilli Mar 18, 2024
1038475
Fix typo
mverzilli Mar 18, 2024
1525d15
Add new spellchecker exception
mverzilli Mar 18, 2024
982570f
Merge branch 'master' into chore/debugger-docs
mverzilli Mar 19, 2024
147b7d7
Replace confusing mention to _hydration_
mverzilli Mar 22, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/docs/how_to/debugger/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"label": "Debugging",
"position": 5,
"collapsible": true,
"collapsed": true
}
175 changes: 175 additions & 0 deletions docs/docs/how_to/debugger/debugging_with_the_repl.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
---
title: Using the REPL Debugger
description:
Step by step guide on how to debug your Noir circuits with the REPL Debugger.
keywords:
[
Nargo,
Noir CLI,
Noir Debugger,
REPL,
]
sidebar_position: 1
---

#### Pre-requisites

In order to use the REPL debugger, first you need to install recent enough versions of Nargo and vscode-noir.

The first versions of each that ship with support for the Noir Debugger are:

- Nargo: > x
- Noir: > y
- vscode-noir: > z

## Debugging a simple circuit

Let's debug a simple circuit:

```rust
fn main(x : Field, y : pub Field) {
assert(x != y);
}
```

To start the REPL debugger, using a terminal, go to a Noir circuit's home directory. Then:

`$ nargo debug`

You should be seeing this in your terminal:

```
[main] Starting debugger
At ~/noir-examples/recursion/circuits/main/src/main.nr:1:9
1 -> fn main(x : Field, y : pub Field) {
2 assert(x != y);
3 }
>
```

The debugger displays the current Noir code location, and it is now waiting for us to drive it.

Let's first take a look at the available commands. For that we'll use the `help` command.

```
> help
Available commands:

opcodes display ACIR opcodes
into step into to the next opcode
next step until a new source location is reached
out step until a new source location is reached
and the current stack frame is finished
break LOCATION:OpcodeLocation add a breakpoint at an opcode location
over step until a new source location is reached
without diving into function calls
restart restart the debugging session
delete LOCATION:OpcodeLocation delete breakpoint at an opcode location
witness show witness map
witness index:u32 display a single witness from the witness map
witness index:u32 value:String update a witness with the given value
memset index:usize value:String update a Brillig memory cell with the given
value
continue continue execution until the end of the
program
vars show variable values available at this point
in execution
stacktrace display the current stack trace
memory show Brillig memory (valid when executing a
Brillig block)
registers show Brillig registers (valid when executing
a Brillig block)
regset index:usize value:String update a Brillig register with the given
value
step step to the next ACIR opcode

Other commands:

help Show this help message
quit Quit repl

```

The command menu is for the most part self-explanatory. Some commands operate only at Brillig level, such as `memory`, `memset`, `registers`, `regset`. If you try to use them while execution is paused at an ACIR opcode, the debugger will simply inform you that you are not executing Brillig code:
mverzilli marked this conversation as resolved.
Show resolved Hide resolved

```
> registers
Brillig VM registers not available
>
```

Before continuing, we can take a look at the initial witness map:

```
> witness
_0 = 1
_1 = 2
>
```

Cool, since `x==1`, `y==2`, and we want to check that `x != y`, our circuit should succeed. At this point we could intervene and use the witness setter command to change one of the witnesses. Let's set `y=3`, then back to 2, so we don't affect the expected result:

```
> witness
_0 = 1
_1 = 2
> witness 1 3
_1 = 3
> witness
_0 = 1
_1 = 3
> witness 1 2
_1 = 2
> witness
_0 = 1
_1 = 2
>
```

Now we can inspect the current state of local variables. For that we use the `vars` command.

```
> vars
>
```

We currently have no vars in context, since we are at the entry point of the program. Let's use `next` to execute until the next point in the program.

```
> vars
> next
At ~/noir-examples/recursion/circuits/main/src/main.nr:1:20
1 -> fn main(x : Field, y : pub Field) {
2 assert(x != y);
3 }
> vars
x:Field = 0x01
```

As a result of stepping, we have now hydrated variable `x`, whose initial value comes from the witness map.
mverzilli marked this conversation as resolved.
Show resolved Hide resolved

```
> next
1 fn main(x : Field, y : pub Field) {
2 -> assert(x != y);
3 }
> vars
y:Field = 0x02
x:Field = 0x01
```

Stepping again we can finally see both variables and their values. And now we can see that the next assertion should succeed.

Let's continue to the end:

```
> continue
(Continuing execution...)
Finished execution
> q
[main] Circuit witness successfully solved
```

Upon quitting the debugger after a solved circuit, the resulting circuit witness gets saved, equivalent to what would happen if we had run the same circuit with `nargo execute`.

We just went through the basics of debugging using Noir REPL debugger. For a comprehensive reference, check out [the reference page](../../reference/debugger/debugger_repl.md).
73 changes: 73 additions & 0 deletions docs/docs/how_to/debugger/debugging_with_vs_code.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
---
title: Using the VS Code Debugger
description:
Step by step guide on how to debug your Noir circuits with the VS Code Debugger configuration and features.
keywords:
[
Nargo,
Noir CLI,
Noir Debugger,
VS Code,
IDE,
]
sidebar_position: 0
---

This guide will show you how to use VS Code with the vscode-noir extension to debug a Noir project.

#### Pre-requisites

- Noir > x
- Nargo > x
- vscode-noir > x
- A Noir project with a `Nargo.toml`, `Prover.toml` and at least one Noir (`.nr`) containing an entry point function (typically `main`).

Once you have installed Nargo and vscode-noir, you should have everything you need to debug your project.

## Running the debugger

The easiest way to start debugging is to open the file you want to debug, and press `F5`. This will cause the debugger to launch, using your `Prover.toml` file as input.

You should see something like this:

![Debugger launched](@site/static/img/debugger/1-started.png)

Let's inspect the state of the program. For that, we open VS Code's _Debug pane_. Look for this icon:

![Debug pane icon](@site/static/img/debugger/2-icon.png)

You will now see three categories of variables: Locals, Witness Map and Brillig Registers.

![Debug pane expanded](@site/static/img/debugger/3-debug-pane.png)

1. **Locals**: variables of your program. At this point in execution this section is empty, but as we step through the code it will get populated by `x`, `result`, `digest`, etc.

2. **Witness map**: these are initially populated from your project's `Prover.toml` file. In this example, they will be used to populate `x` and `result` at the beginning of the `main` function.

3. **Brillig registers**: these show the current state of the BrilligVM registers.
mverzilli marked this conversation as resolved.
Show resolved Hide resolved

Most of the time you will probably be focusing mostly on locals, as they represent the high level state of your program.

You might be interested in inspecting the witness map and Brillig registers in case you are trying to solve a really low level issue in the compiler or runtime itself, so these concern mostly advanced or niche users.

Let's step through the program, by using the debugger buttons or their corresponding keyboard shortcuts.

![Debugger buttons](@site/static/img/debugger/4-debugger-buttons.png)

Now we can see in the variables pane that there's values for `digest`, `result` and `x`.

![Inspecting locals](@site/static/img/debugger/5-assert.png)

We can also inspect the values of variables by directly hovering on them on the code.

![Hover locals](@site/static/img/debugger/6-hover.png)

Let's set a break point at the `keccak256` function, so we can continue execution up to the point when it's first invoked without having to go one step at a time.

We just need to click the to the right of the line number 18. Once the breakpoint appears, we can click the `continue` button or use its corresponding keyboard shortcut (`F5` by default).

![Breakpoint](@site/static/img/debugger/7-break.png)

Now we are debugging the `keccak256` function, notice the _Call Stack pane_ at the lower right. This lets us inspect the current call stack of our process.

That covers most of the current debugger functionalities. Check out [the reference](../../reference/debugger/debugger_vscode.md) for more details on how to configure the debugger.
1 change: 1 addition & 0 deletions docs/docs/how_to/merkle-proof.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ description:
merkle tree with a specified root, at a given index.
keywords:
[merkle proof, merkle membership proof, Noir, rust, hash function, Pedersen, sha256, merkle tree]
sidebar_position: 4
---

Let's walk through an example of a merkle membership proof in Noir that proves that a given leaf is
Expand Down
4 changes: 2 additions & 2 deletions docs/docs/noir/concepts/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ fn main(x : [Field]) // can't compile, has variable size
fn main(....// i think you got it by now
```

Keep in mind [tests](../../getting_started/tooling/testing.md) don't differentiate between `main` and any other function. The following snippet passes tests, but won't compile or prove:
Keep in mind [tests](../tooling/testing.md) don't differentiate between `main` and any other function. The following snippet passes tests, but won't compile or prove:

```rust
fn main(x : [Field]) {
Expand Down Expand Up @@ -190,7 +190,7 @@ Supported attributes include:
- **deprecated**: mark the function as _deprecated_. Calling the function will generate a warning: `warning: use of deprecated function`
- **field**: Used to enable conditional compilation of code depending on the field size. See below for more details
- **oracle**: mark the function as _oracle_; meaning it is an external unconstrained function, implemented in noir_js. See [Unconstrained](./unconstrained.md) and [NoirJS](../../reference/NoirJS/noir_js/index.md) for more details.
- **test**: mark the function as unit tests. See [Tests](../../getting_started/tooling/testing.md) for more details
- **test**: mark the function as unit tests. See [Tests](../tooling/testing.md) for more details

### Field Attribute

Expand Down
mverzilli marked this conversation as resolved.
Show resolved Hide resolved
File renamed without changes.
100 changes: 100 additions & 0 deletions docs/docs/noir/tooling/debugger.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
---
title: Debugger
description: Learn about the Noir Debugger, in its REPL or VS Code versions.
keywords: [Nargo, VSCode, Visual Studio Code, REPL, Debugger]
sidebar_position: 2
---

# Noir Debugger

There are currently two ways of debugging Noir programs:

1. From VS Code, via the [vscode-noir](https://github.com/noir-lang/vscode-noir) extension. You can install it via the [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=noir-lang.vscode-noir).
2. Via the REPL debugger, which ships with Nargo.

In order to use either version of the debugger, you will need to install recent enough versions of Noir, [Nargo](../../getting_started/installation) and vscode-noir:

- Noir 0.xx
- Nargo 0.xx
- vscode-noir 0.xx

:::info
At the moment, the debugger supports debugging binary projects, but not contracts.
:::

## VS Code debugger quickstart

Once you installed Nargo and the vscode-noir extension, you can start debugging your Noir programs by simply opening a `.nr` file, clicking the debugger pane, and clicking _Run and debug_. Alternatively you can just use the `F5` keyboard shortcut.

You should be seeing something like this:

![Screencast of VS Code Noir Debugger](@site/static/img/debugger/debugger-intro.gif)
)

We cover the VS Code Noir debugger more in depth in [its how-to guide](../../how_to/debugger/debugging_with_vs_code.md) and [its reference](../../reference/debugger/debugger_vscode.md).

## REPL debugger quickstart
mverzilli marked this conversation as resolved.
Show resolved Hide resolved

Let's debug a simple circuit:

```rust
fn main(x : Field, y : pub Field) {
assert(x != y);
}
```

To start the REPL debugger, using a terminal, go to a Noir circuit's home directory. Then:

`$ nargo debug`

You should be seeing something similar to this in your terminal:

```
[main] Starting debugger
At ~/noir-examples/recursion/circuits/main/src/main.nr:2:12
1 fn main(x : Field, y : pub Field) {
2 -> assert(x != y);
3 }
>
```


That's it! The debugger displays the current Noir code location, and it is now waiting for us to drive it. You can explore the available commands to drive the debugger with `help`, like here:

```
At ~/noir-examples/recursion/circuits/main/src/main.nr:2:12
1 fn main(x : Field, y : pub Field) {
2 -> assert(x != y);
3 }
> help
Available commands:

break LOCATION:OpcodeLocation add a breakpoint at an opcode location
memory show Brillig memory (valid when executing a
Brillig block)
into step into to the next opcode
next step until a new source location is reached
delete LOCATION:OpcodeLocation delete breakpoint at an opcode location
step step to the next ACIR opcode
registers show Brillig registers (valid when executing
a Brillig block)
regset index:usize value:String update a Brillig register with the given
value
restart restart the debugging session
witness show witness map
witness index:u32 display a single witness from the witness map
witness index:u32 value:String update a witness with the given value
continue continue execution until the end of the
program
opcodes display ACIR opcodes
memset index:usize value:String update a Brillig memory cell with the given
value

Other commands:

help Show this help message
quit Quit repl
```


We'll cover each command in depth in [the REPL debugger how-to](../../how_to/debugger/debugging_with_the_repl.md) and [its reference](../../reference/debugger/debugger_repl.md).
6 changes: 6 additions & 0 deletions docs/docs/reference/debugger/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"label": "Debugger",
"position": 1,
"collapsible": true,
"collapsed": true
}
Loading