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: regression test #7195 #7233

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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 test_programs/execution_success/regression_7195/Nargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
name = "regression_7195"
type = "bin"
authors = [""]

[dependencies]
2 changes: 2 additions & 0 deletions test_programs/execution_success/regression_7195/Prover.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
x = "1"
y = "2"
13 changes: 13 additions & 0 deletions test_programs/execution_success/regression_7195/src/main.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
fn bar(y: Field) {
assert(y != 0);
}

fn foo(x: Field) {
bar(x)
}

fn main(x: Field, y: pub Field) {
foo(x);
foo(y);
assert(x != y);
}
3 changes: 2 additions & 1 deletion tooling/debugger/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ pub fn run_repl_session<B: BlackBoxFunctionSolver<FieldElement>>(
solver: &B,
program: CompiledProgram,
initial_witness: WitnessMap<FieldElement>,
raw_source_printing: bool,
) -> Result<Option<WitnessStack<FieldElement>>, NargoError<FieldElement>> {
repl::run(solver, program, initial_witness)
repl::run(solver, program, initial_witness, raw_source_printing)
}

pub fn run_dap_loop<R: Read, W: Write, B: BlackBoxFunctionSolver<FieldElement>>(
Expand Down
15 changes: 13 additions & 2 deletions tooling/debugger/src/repl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ pub struct ReplDebugger<'a, B: BlackBoxFunctionSolver<FieldElement>> {

// Brillig functions referenced from the ACIR circuits above
unconstrained_functions: &'a [BrilligBytecode<FieldElement>],

// whether to print the source without highlighting / pretty-printing
raw_source_printing: bool,
}

impl<'a, B: BlackBoxFunctionSolver<FieldElement>> ReplDebugger<'a, B> {
Expand All @@ -41,6 +44,7 @@ impl<'a, B: BlackBoxFunctionSolver<FieldElement>> ReplDebugger<'a, B> {
debug_artifact: &'a DebugArtifact,
initial_witness: WitnessMap<FieldElement>,
unconstrained_functions: &'a [BrilligBytecode<FieldElement>],
raw_source_printing: bool,
) -> Self {
let foreign_call_executor = Box::new(DefaultDebugForeignCallExecutor::from_artifact(
PrintOutput::Stdout,
Expand Down Expand Up @@ -68,6 +72,7 @@ impl<'a, B: BlackBoxFunctionSolver<FieldElement>> ReplDebugger<'a, B> {
initial_witness,
last_result,
unconstrained_functions,
raw_source_printing,
}
}

Expand Down Expand Up @@ -97,7 +102,11 @@ impl<'a, B: BlackBoxFunctionSolver<FieldElement>> ReplDebugger<'a, B> {
}
}
let locations = self.context.get_source_location_for_debug_location(&location);
print_source_code_location(self.debug_artifact, &locations);
print_source_code_location(
self.debug_artifact,
&locations,
self.raw_source_printing,
);
}
}
}
Expand Down Expand Up @@ -125,7 +134,7 @@ impl<'a, B: BlackBoxFunctionSolver<FieldElement>> ReplDebugger<'a, B> {
}
}
let locations = self.context.get_source_location_for_debug_location(debug_location);
print_source_code_location(self.debug_artifact, &locations);
print_source_code_location(self.debug_artifact, &locations, self.raw_source_printing);
}

pub fn show_current_call_stack(&self) {
Expand Down Expand Up @@ -427,6 +436,7 @@ pub fn run<B: BlackBoxFunctionSolver<FieldElement>>(
blackbox_solver: &B,
program: CompiledProgram,
initial_witness: WitnessMap<FieldElement>,
raw_source_printing: bool,
) -> Result<Option<WitnessStack<FieldElement>>, NargoError<FieldElement>> {
let circuits = &program.program.functions;
let debug_artifact =
Expand All @@ -438,6 +448,7 @@ pub fn run<B: BlackBoxFunctionSolver<FieldElement>>(
debug_artifact,
initial_witness,
unconstrained_functions,
raw_source_printing,
));
let ref_context = &context;

Expand Down
32 changes: 27 additions & 5 deletions tooling/debugger/src/source_code_printer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ struct LocationPrintContext {
// Given a DebugArtifact and an OpcodeLocation, prints all the source code
// locations the OpcodeLocation maps to, with some surrounding context and
// visual aids to highlight the location itself.
pub(super) fn print_source_code_location(debug_artifact: &DebugArtifact, locations: &[Location]) {
pub(super) fn print_source_code_location(
debug_artifact: &DebugArtifact,
locations: &[Location],
raw_source_printing: bool,
) {
let locations = locations.iter();

for loc in locations {
Expand All @@ -41,9 +45,11 @@ pub(super) fn print_source_code_location(debug_artifact: &DebugArtifact, locatio
for line in lines {
match line {
PrintedLine::Skip => {}
PrintedLine::Ellipsis { line_number } => print_ellipsis(line_number),
PrintedLine::Ellipsis { line_number } => {
print_ellipsis(line_number, raw_source_printing)
}
PrintedLine::Content { line_number, cursor, content, highlight } => {
print_content(line_number, cursor, content, highlight)
print_content(line_number, cursor, content, highlight, raw_source_printing)
}
}
}
Expand All @@ -57,11 +63,27 @@ fn print_location_path(debug_artifact: &DebugArtifact, loc: Location) {
println!("At {}:{line_number}:{column_number}", debug_artifact.name(loc.file).unwrap());
}

fn print_ellipsis(line_number: usize) {
fn print_ellipsis(line_number: usize, raw_source_printing: bool) {
if raw_source_printing {
println!("...");
return;
}

println!("{:>3} {:2} {}", line_number.dimmed(), "", "...".dimmed());
}

fn print_content(line_number: usize, cursor: &str, content: &str, highlight: Option<Range<usize>>) {
fn print_content(
line_number: usize,
cursor: &str,
content: &str,
highlight: Option<Range<usize>>,
raw_source_printing: bool,
) {
if raw_source_printing {
println!("{}", content);
return;
}

match highlight {
Some(highlight) => {
println!(
Expand Down
108 changes: 108 additions & 0 deletions tooling/debugger/tests/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,112 @@ mod tests {
// Exit the bash session.
dbg_session.send_line("exit").expect("Failed to quit bash session");
}

#[test]
fn debugger_expected_call_stack() {
let nargo_bin =
cargo_bin("nargo").into_os_string().into_string().expect("Cannot parse nargo path");

let timeout_seconds = 30;
let mut dbg_session =
spawn_bash(Some(timeout_seconds * 1000)).expect("Could not start bash session");

let test_program_path = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
.join("../../test_programs/execution_success/regression_7195");
let test_program_dir = test_program_path.display();

// Start debugger and test that it loads for the given program.
dbg_session
.execute(
&format!(
"{nargo_bin} debug --raw-source-printing true --program-dir {test_program_dir} --force-brillig --expression-width 3"
),
".*\\Starting debugger.*",
)
.expect("Could not start debugger");

for step_number in 0..8 {
// While running the debugger, issue a "next" cmd,
// which should run to the program to the next source line given
// we haven't set any breakpoints.
// ">" is the debugger's prompt, so finding one
// after running "next" indicates that the
// debugger has not panicked for this step.
dbg_session
.send_line("next")
.expect("Debugger panicked while attempting to step through program.");
dbg_session
.exp_string(">")
.expect("Failed while waiting for debugger to step through program.");

if step_number == 7 {
let mut lines = vec![];
let mut read_line = dbg_session.read_line();
while read_line.is_ok() {
if let Ok(line) = read_line {
// only keep the results after the most recent "next" command
if line.contains("> next") {
lines = vec![];
} else {
lines.push(line);
}
}
read_line = dbg_session.read_line();
}

let lines_expected_to_contain: Vec<&str> = vec![
"At opcode ",
"At ",
"...",
" bar(x)",
"}",
"",
"fn main(x: Field, y: pub Field) {",
" foo(x);",
" foo(y);",
" assert(x != y);",
"}",
"At ",
"fn bar(y: Field) {",
" assert(y != 0);",
"}",
"",
"fn foo(x: Field) {",
" bar(x)",
"}",
"",
"fn main(x: Field, y: pub Field) {",
" foo(x);",
"...",
"At ",
"fn bar(y: Field) {",
" assert(y != 0);",
"}",
"",
"fn foo(x: Field) {",
" bar(x)",
"...",
];

for (line, line_expected_to_contain) in
lines.into_iter().zip(lines_expected_to_contain)
{
let ascii_line: String = line.chars().filter(char::is_ascii).collect();
let line_expected_to_contain = line_expected_to_contain.trim_start();
assert!(
ascii_line.contains(line_expected_to_contain),
"{:?}\ndid not contain\n{:?}",
ascii_line,
line_expected_to_contain,
);
}
}
}

// Run the "quit" command
dbg_session.send_line("quit").expect("Failed to quit debugger");

// Exit the bash session.
dbg_session.send_line("exit").expect("Failed to quit bash session");
}
}
20 changes: 17 additions & 3 deletions tooling/nargo_cli/src/cli/debug_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ pub(crate) struct DebugCommand {
/// Disable vars debug instrumentation (enabled by default)
#[clap(long)]
skip_instrumentation: Option<bool>,

/// Raw string printing of source for testing
#[clap(long, hide = true, default_value = "false")]
raw_source_printing: Option<bool>,
}

pub(crate) fn run(args: DebugCommand, config: NargoConfig) -> Result<(), CliError> {
Expand Down Expand Up @@ -92,6 +96,7 @@ pub(crate) fn run(args: DebugCommand, config: NargoConfig) -> Result<(), CliErro
&args.witness_name,
target_dir,
args.compile_options.pedantic_solving,
args.raw_source_printing.unwrap_or(false),
)
}

Expand Down Expand Up @@ -180,14 +185,20 @@ fn run_async(
witness_name: &Option<String>,
target_dir: &PathBuf,
pedantic_solving: bool,
raw_source_printing: bool,
) -> Result<(), CliError> {
use tokio::runtime::Builder;
let runtime = Builder::new_current_thread().enable_all().build().unwrap();

runtime.block_on(async {
println!("[{}] Starting debugger", package.name);
let (return_value, witness_stack) =
debug_program_and_decode(program, package, prover_name, pedantic_solving)?;
let (return_value, witness_stack) = debug_program_and_decode(
program,
package,
prover_name,
pedantic_solving,
raw_source_printing,
)?;

if let Some(solved_witness_stack) = witness_stack {
println!("[{}] Circuit witness successfully solved", package.name);
Expand Down Expand Up @@ -215,12 +226,13 @@ fn debug_program_and_decode(
package: &Package,
prover_name: &str,
pedantic_solving: bool,
raw_source_printing: bool,
) -> Result<(Option<InputValue>, Option<WitnessStack<FieldElement>>), CliError> {
// Parse the initial witness values from Prover.toml
let (inputs_map, _) =
read_inputs_from_file(&package.root_dir, prover_name, Format::Toml, &program.abi)?;
let program_abi = program.abi.clone();
let witness_stack = debug_program(program, &inputs_map, pedantic_solving)?;
let witness_stack = debug_program(program, &inputs_map, pedantic_solving, raw_source_printing)?;

match witness_stack {
Some(witness_stack) => {
Expand All @@ -239,13 +251,15 @@ pub(crate) fn debug_program(
compiled_program: CompiledProgram,
inputs_map: &InputMap,
pedantic_solving: bool,
raw_source_printing: bool,
) -> Result<Option<WitnessStack<FieldElement>>, CliError> {
let initial_witness = compiled_program.abi.encode(inputs_map, None)?;

noir_debugger::run_repl_session(
&Bn254BlackBoxSolver(pedantic_solving),
compiled_program,
initial_witness,
raw_source_printing,
)
.map_err(CliError::from)
}
Loading