-
Notifications
You must be signed in to change notification settings - Fork 200
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
Comments
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:
Happy to support either way 🙌 |
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. |
@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 :) |
@mverzilli thanks! Both approaches are very reasonable, simply making sure we are aligned on one 👍 |
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. |
# 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.
# 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>
…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.
# 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.
# 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.
# 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>
…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.
# 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>
# 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.
# 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>
# 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>
# 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.
@Savio-Sou how do you usually handle these "umbrella" issues? The debugger MVP is now fully merged so I was considering closing this. |
Hey, yep I think we can close this issue and just have individual issues for the debugger from now on. |
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:
nargo debug
)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! :).
Before Release
to_le_bytes
/to_be_bytes
return fixed size arrays when applied to constants #4048constant_to_radix
emit a slice instead of an array #4049Done
Debugger core
REPL Debugger
VS Code Debugger
Misc
Support for Aztec contracts debugging
After first release
Post MVP
The text was updated successfully, but these errors were encountered: