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

Epic: Noir Debugger MVP #3015

Closed
25 of 38 tasks
mverzilli opened this issue Oct 6, 2023 · 7 comments
Closed
25 of 38 tasks

Epic: Noir Debugger MVP #3015

mverzilli opened this issue Oct 6, 2023 · 7 comments
Labels
debugger enhancement New feature or request
Milestone

Comments

@mverzilli
Copy link
Contributor

mverzilli commented Oct 6, 2023

Problem

This is a tracking issue for the implementation of a debugger for Noir. Initially, there's going to be at least 2 ways of debugging Noir code:

  1. REPL based, via Nargo (nargo debug)
  2. In VS Code, through the official Noir VS Code extension

We're beginning to explore what it would take to allow users to debug Noir contracts. The two options above are not enough to that end, because Noir contracts depend on a rich stateful environment, such as the Aztec Sandbox. At the moment we think then the Aztec Sandbox should expose a DAP server implementation for external consumption.

This list will be updated/extended as we surface more features and/or necessary foundational work.

Any ideas and wants are welcome and can be considered, just comment here! :).

Done

Debugger core

REPL Debugger

VS Code Debugger

Misc

Support for Aztec contracts debugging

After first release

Post MVP

@Savio-Sou
Copy link
Collaborator

Hi @mverzilli,

Welcome to the community and thank you for creating the Epic!

Would you prefer documenting and announcing from Noir's social media outlets:

  • Each sub-feature merged (which helps garner community interests and contributions as we go), or
  • When the Epic is completed?

Happy to support either way 🙌

@mverzilli
Copy link
Contributor Author

Hi @Savio-Sou! I'm leaning towards when the epic is completed. Things are likely to change shape quickly as we grow the debugger at this phase, so early comms might confuse the community. I'll do my best to help this converge to a minimal first version in as much as a straight line as possible.

@mverzilli
Copy link
Contributor Author

@Savio-Sou that said, I ultimately defer to your opinion! If you think it's a good idea to somehow share a sneak peek of this I'm open to it as well :)

@Savio-Sou
Copy link
Collaborator

@mverzilli thanks! Both approaches are very reasonable, simply making sure we are aligned on one 👍

@Savio-Sou
Copy link
Collaborator

Savio-Sou commented Oct 27, 2023

On that note definitely feel free to share your WIP if you're attending Devconnect / doing any talks soon. No pressure to feel the need to "censor" or "remain in stealth" at all.

@mverzilli mverzilli changed the title Epic: Implement Noir REPL-based debugger Epic: Implement Noir debugger Nov 3, 2023
@Savio-Sou Savio-Sou added this to the 1.0 milestone Nov 22, 2023
github-merge-queue bot pushed a commit that referenced this issue Dec 11, 2023
# Description

Adds a first guide on how to use the REPL debugger with binary Noir
programs, and a discussion of (currently) experimental features.

To be soon expanded with more details on how to test more
experimental/not-yet-completed features.

## Problem

Part of #3015. 

## Documentation

Check one:
- [ ] No documentation needed.
- [x] Documentation included in this PR.
- [ ] **[Exceptional Case]** Documentation to be submitted in a separate
PR.

# PR Checklist\*

- [x] I have tested the changes locally.
- [x] I have formatted the changes with [Prettier](https://prettier.io/)
and/or `cargo fmt` on default settings.
github-merge-queue bot pushed a commit that referenced this issue Dec 19, 2023
# Description

Implements the DAP protocol to allow a tool such as VS.Code to drive the
debugger in a Noir binary project. A separate PR for the [VS.Code Noir
extension](https://github.com/noir-lang/vscode-noir) will be submitted
later.

## Problem

Part of #3015 

The beginning of this implementation was heavily inspired by @dmvict
[implementation](#3094) of an
alternative debugger for Noir programs.

## Summary

This PR implements a new `nargo` subcommand `dap`. This starts a DAP
server in single session mode through stdin/stdout and waits for a
launch request. Using the arguments in the launch request
(`projectFolder`, and optionally `package` and `proverName`) it compiles
the Noir binary package and starts it in debug mode. Through DAP
requests, a tool can then step through the program, set breakpoints and
list the generated opcodes using a disassemble request.

## Additional Context



## Documentation

Check one:
- [ ] No documentation needed.
- [ ] Documentation included in this PR.
- [X] **[Exceptional Case]** Documentation to be submitted in a separate
PR.

# PR Checklist\*

- [X] I have tested the changes locally.
- [X] I have formatted the changes with [Prettier](https://prettier.io/)
and/or `cargo fmt` on default settings.

---------

Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com>
github-merge-queue bot pushed a commit that referenced this issue Dec 20, 2023
…res (#3853)

# Description

There's a number of debugger features that are in active development and
that can't yet be merged to the main branch for different reasons. This
changeset adds a summary of what those features are and how to try them
out.

## Problem

Part of #3015. 

## Summary

Adds instructions on how to test experimental debugger features to the
debugger's README.md file.

## Documentation

Check one:
- [ ] No documentation needed.
- [x] Documentation included in this PR.
- [ ] **[Exceptional Case]** Documentation to be submitted in a separate
PR.

# PR Checklist\*

- [x] I have tested the changes locally.
- [x] I have formatted the changes with [Prettier](https://prettier.io/)
and/or `cargo fmt` on default settings.
github-merge-queue bot pushed a commit that referenced this issue Jan 4, 2024
# Description

Adds integration tests for the debugger. 

## Problem

Related to #3015. Generates a new suite of tests that uses the examples
at test_programs/execution_success to verify that the debugger can be
started and stepped to completion with those examples.

## Summary

We take the same approach used for the `nargo execute` cmd: generating
test cases from those at test_programs/execution_success. This means
future extensions to the Noir language captured in those examples will
automatically be included in the debugger integration suite, and will
help detect any potential divergence between the language runtime and
the debugger instrumentation.

## Documentation

Check one:
- [x] No documentation needed.
- [ ] Documentation included in this PR.
- [ ] **[Exceptional Case]** Documentation to be submitted in a separate
PR.

# PR Checklist\*

- [x] I have tested the changes locally.
- [x] I have formatted the changes with [Prettier](https://prettier.io/)
and/or `cargo fmt` on default settings.
github-merge-queue bot pushed a commit that referenced this issue Jan 16, 2024
# Description

The compiler optimizes uses of the `ToRadix` intrinsic applied to
constants by precomputing the results.

## Problem\*

Resolves #4048

The optimization produces a fixed sized array instead of a slice.

## Summary\*

The PR changes the `constant_to_radix` function to produce a slice and
generates a tuple with the length and the slice itself, which fits the
internal representation of slices in SSA.

## Additional Context

This was found and fixed during the implementation of the debugger (see
#3015).

## Documentation\*

Check one:
- [X] No documentation needed.
- [ ] Documentation included in this PR.
- [ ] **[Exceptional Case]** Documentation to be submitted in a separate
PR.

# PR Checklist\*

- [X] I have tested the changes locally.
- [X] I have formatted the changes with [Prettier](https://prettier.io/)
and/or `cargo fmt` on default settings.
github-merge-queue bot pushed a commit that referenced this issue Jan 18, 2024
# Description

## Problem\*

As part of our debugger implementation (see #3015) we need to extend the
supported types that can be printed. We are using `noirc_printable_type`
to keep values of variables at runtime for debug inspection.

Also resolves #4073

## Summary\*

This PR adds support for converting these new types:

- Tuples
- Slices: lift the restriction to print them and handle arrays with
dynamic size (flagging them with a `None` length in the type)
- Functions: printed as an opaque `<<function>>` tag for now
- Mutable references: printed as an opaque `<<mutable ref>>` tag for now
- Unit: this is actually required to fully support function type
conversion, for non-closured function references (ie. the environment is
`()` in that case)

The PR also fixes a preexisting bug when printing multiple values using
formatted strings with the first ones being structs. Since structs are
expanded into tuples which take up more than one field, the printing
code would fail to skip over all the fields of the struct.

## Additional Context

I've been using [this
program](https://gist.github.com/ggiraldez/e3709def6c26e7585d12002fc8a0a216)
to test this functionality. If it makes sense, I can add it as an
integration test to `test_programs/execution_success`.

The program produces this output:
```
(0x01, 0x02, 0x03)
0xbbbb # a = (0x01, 0x02, 0x03) # 0xeeee
(0x01, 0x02, 0x03) == (0x01, 0x02, 0x03)

((0x01, 0x02, 0x03), 0x04, 0x05, 0x06)
0xbbbb # b = ((0x01, 0x02, 0x03), 0x04, 0x05, 0x06) # 0xeeee
((0x01, 0x02, 0x03), 0x04, 0x05, 0x06) == ((0x01, 0x02, 0x03), 0x04, 0x05, 0x06)

<<mutable ref>>
0xbbbb # c = <<mutable ref>> # 0xeeee

<<function>>
0xbbbb # d = <<function>> # 0xeeee

<<function>>
0xbbbb # f = <<function>> # 0xeeee

[0x01, 0x02, 0x03]
0xbbbb # g = [0x01, 0x02, 0x03] # 0xeeee
[0x01, 0x02, 0x03] == [0x01, 0x02, 0x03]

Foo { x: 555, y: 666 } == Foo { x: 555, y: 666 }

Vec { slice: [0x01, 0x02] }
0xbbbb # h = Vec { slice: [0x01, 0x02] } # 0xeeee

[0x01, 0x02]
0xbbbb # j = [0x01, 0x02] # 0xeeee
[0x01, 0x02] == [0x01, 0x02]

[printable_types] Circuit witness successfully solved
```

## Documentation\*

Check one:
- [X] No documentation needed.
- [ ] Documentation included in this PR.
- [ ] **[Exceptional Case]** Documentation to be submitted in a separate
PR.

# PR Checklist\*

- [X] I have tested the changes locally.
- [X] I have formatted the changes with [Prettier](https://prettier.io/)
and/or `cargo fmt` on default settings.

---------

Co-authored-by: synthia <sy@nthia.dev>
github-merge-queue bot pushed a commit that referenced this issue Jan 24, 2024
…REPL debugger (#4147)

# Description

Reduces the amount of information printed to the console after each
step, when execution pauses at an ACIR BRILLIG opcode.

## Problem

Part of #3015. 

## Summary

Before this change:

```
[1327_concrete_in_generic] Starting debugger
At opcode 0: BRILLIG: inputs: [Single(Expression { mul_terms: [], linear_combinations: [], q_c: 0 }), Single(Expression { mul_terms: [], linear_combinations: [(1, Witness(0))], q_c: 0 })]
outputs: []
[Mov { destination: RegisterIndex(2), source: RegisterIndex(0) }, Mov { destination: RegisterIndex(3), source: RegisterIndex(1) }, Const { destination: RegisterIndex(0), value: Value { inner: 0 } }, Const { destination: RegisterIndex(1), value: Value { inner: 0 } }, Mov { destination: RegisterIndex(2), source: RegisterIndex(2) }, Mov { destination: RegisterIndex(3), source: RegisterIndex(3) }, Call { location: 8 }, Stop, ForeignCall { function: "__debug_var_assign", destinations: [], inputs: [RegisterIndex(RegisterIndex(2)), RegisterIndex(RegisterIndex(3))] }, Return]

At ~/noir/test_programs/execution_success/1327_concrete_in_generic/src/main.nr:56:9
 51    ...
 52    fn get_d_method_interface() -> MethodInterface<D> {
 53        MethodInterface { some_method_on_t_d: d_method }
 54    }
 55    // ---
 56 -> fn main(input: Field) -> pub Field {
 57        let b: B<C<D>> = B::new(new_concrete_c_over_d);
 58        let c: C<D> = b.get_t_c(); // Singleton<Note>
 59        let d: D = D { d: input }; // Note
 60        let output = c.call_method_of_t_d(d);
```

After this change:

```
[1327_concrete_in_generic] Starting debugger
At opcode 0: BRILLIG: ...
At ~/noir/test_programs/execution_success/1327_concrete_in_generic/src/main.nr:56:9
 51    ...
 52    fn get_d_method_interface() -> MethodInterface<D> {
 53        MethodInterface { some_method_on_t_d: d_method }
 54    }
 55    // ---
 56 -> fn main(input: Field) -> pub Field {
 57        let b: B<C<D>> = B::new(new_concrete_c_over_d);
 58        let c: C<D> = b.get_t_c(); // Singleton<Note>
 59        let d: D = D { d: input }; // Note
 60        let output = c.call_method_of_t_d(d);
 61    ...
>
```

Note: the user can still inspect the full contents of opcode 0 by using
the `opcodes` command.


## Documentation

Check one:
- [x] No documentation needed.
- [ ] Documentation included in this PR.
- [ ] **[Exceptional Case]** Documentation to be submitted in a separate
PR.

# PR Checklist

- [x] I have tested the changes locally.
- [x] I have formatted the changes with [Prettier](https://prettier.io/)
and/or `cargo fmt` on default settings.
github-merge-queue bot pushed a commit that referenced this issue Feb 5, 2024
# Description

## Problem\*

Part of #3015 

## Summary\*

This PR injects instrumentation snippets to the compiled code when
running under a debugger to track the values assigned to variables in
the program. It also provides the debugging context with necessary
support code (in the form of foreign functions) and new functionality to
inspect the tracked values.

Instrumentation occurs in two phases:

1. During parsing, when assignments are detected, they are replaced by a
small snippet that captures the value assigned and a temporary
identifier for the variable being assigned, and a foreign function
(oracle) is called with this information.
2. At monomorphization time, ie. after the exact types of all variables
has been determined, replacing the temporary identifier by a final one
which will depend on the variable itself and the type at each instance
of the function being compiled (for generic functions). Also, since
structs are replaced for tuples during compilation, at this stage field
and other member accesses is resolved for the final types (ie. indices
in the tuples).

## Additional Context

Besides the runtime support in the debugger, the compiler also injects a
synthetic crate `__debug` which holds the definition of the oracle
functions used in the injected code for tracking the variables and their
assigned values.

These changes were extracted from the `dap-with-vars` branch of
`manastech/noir` repository where most of the development of this
feature occurred. We will submit additional PRs for the remaining
features in that branch, notably improved REPL and DAP support to make
use of this instrumentation code.

## Documentation\*

Check one:
- [ ] No documentation needed.
- [ ] Documentation included in this PR.
- [X] **[Exceptional Case]** Documentation to be submitted in a separate
PR.

# PR Checklist\*

- [X] I have tested the changes locally.
- [X] I have formatted the changes with [Prettier](https://prettier.io/)
and/or `cargo fmt` on default settings.

---------

Co-authored-by: synthia <sy@nthia.dev>
Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com>
github-merge-queue bot pushed a commit that referenced this issue Feb 8, 2024
# Description

## Problem\*

Part of #3015

Resolves #4025

## Summary\*

This PR adds several features to the debugger:
- (REPL) New command `stacktrace` to display the stack of the current
call frames.
- (REPL) New commands `over` and `out` to step to the next source code
location while staying without going into function calls or out of the
current stack frame.
- (DAP) The debugger commands "Step Into", "Step Out" and "Step Over"
now should work properly.
- (DAP) Return the stacktrace for the corresponding IDE panel.
- (DAP) Return the variables and Brillig registers for the corresponding
Variables panel in the IDE.

## Additional Context

## Documentation\*

Check one:
- [ ] No documentation needed.
- [ ] Documentation included in this PR.
- [X] **[Exceptional Case]** Documentation to be submitted in a separate
PR.

# PR Checklist\*

- [X] I have tested the changes locally.
- [X] I have formatted the changes with [Prettier](https://prettier.io/)
and/or `cargo fmt` on default settings.
github-merge-queue bot pushed a commit that referenced this issue Feb 14, 2024
# Description

## Problem\*

Part of #3015 

## Summary\*

This PR adds a preflight mode to DAP in order to make it easier to
identify and report back problems to the user when compiling the project
for debugging. This preflight mode is invoked from the VS.Code extension
before starting the debugging session, and with the same arguments as
those that will be used for the session. If the compiler finds any error
either loading or compiling the project, the error is reported to stderr
which allows the extension to parse the output and present the
diagnostic messages to the user.

This also changes the default compilation mode to output Brillig code
and adds new commands line options to Nargo's `debug` command and launch
options to the DAP mode to control the mode and whether to inject
instrumentation code to track variables or not.

The `debug` options are:
- `--acir-mode`, force output of ACIR, which disables instrumentation by
default
- `--skip-instrumentation={true,false}` to control injection of
instrumentation code to track variables values during the debugging
session.

Similarly, for DAP two launch options can be provided: `generateAcir`
and `skipInstrumentation`.

## Additional Context

The default is to output in Brillig mode with instrumentation for
tracking variables, as this makes it easier to follow along with
stepping through the code. If ACIR mode is selected, instrumentation is
disabled by default. Instrumentation can be forcefully enabled or
disabled by the provided CLI option.

## Documentation\*

Check one:
- [ ] No documentation needed.
- [ ] Documentation included in this PR.
- [X] **[Exceptional Case]** Documentation to be submitted in a separate
PR.

# PR Checklist\*

- [X] I have tested the changes locally.
- [X] I have formatted the changes with [Prettier](https://prettier.io/)
and/or `cargo fmt` on default settings.

---------

Co-authored-by: Martin Verzilli <martin.verzilli@gmail.com>
github-merge-queue bot pushed a commit that referenced this issue Mar 7, 2024
# Description

## Problem\*

Part of #3015

We want to track call frames and observe variables local to the
currently executing frame.

## Summary\*

This PR adds a bit more debugging instrumentation to track when function
call frames are entered and exited, which allows to determine which
variables are "live" at the current point in execution. This new
instrumentation also allows labeling the frames in the call stack from
the names of the functions being executed.

Also, it includes improvements on how source breakpoints are mapped into
opcode breakpoints. Both features combined bring substantial
improvements to the debugger usability.

## Additional Context

## Documentation\*

Check one:
- [ ] No documentation needed.
- [ ] Documentation included in this PR.
- [X] **[Exceptional Case]** Documentation to be submitted in a separate
PR.

# PR Checklist\*

- [X] I have tested the changes locally.
- [X] I have formatted the changes with [Prettier](https://prettier.io/)
and/or `cargo fmt` on default settings.

---------

Co-authored-by: synthia <sy@nthia.dev>
Co-authored-by: Martin Verzilli <martin.verzilli@gmail.com>
github-merge-queue bot pushed a commit that referenced this issue Apr 12, 2024
# Description

Adds documentation for the Noir debugger.

## Problem

Part of #3015.

## Summary

Adds quickstart, how to's and reference pages to Noir's docsite covering
both the VS Code and REPL debuggers.

## Documentation

Check one:
- [ ] No documentation needed.
- [x] Documentation included in this PR.
- [ ] **[Exceptional Case]** Documentation to be submitted in a separate
PR.

# PR Checklist\*

- [x] I have tested the changes locally.
- [x] I have formatted the changes with [Prettier](https://prettier.io/)
and/or `cargo fmt` on default settings.
@mverzilli
Copy link
Contributor Author

@Savio-Sou how do you usually handle these "umbrella" issues? The debugger MVP is now fully merged so I was considering closing this.

@github-project-automation github-project-automation bot moved this from 📋 Backlog to ✅ Done in Noir Apr 18, 2024
@TomAFrench
Copy link
Member

Hey, yep I think we can close this issue and just have individual issues for the debugger from now on.

@Savio-Sou Savio-Sou changed the title Epic: Implement Noir debugger Epic: Noir Debugger MVP Apr 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
debugger enhancement New feature or request
Projects
Archived in project
Development

No branches or pull requests

3 participants