Path: blob/main/tests/all/native_debug/lldb.rs
2450 views
use anyhow::{Result, bail, format_err};1use filecheck::{CheckerBuilder, NO_VARIABLES};2use std::env;3use std::io::Write;4use std::process::Command;5use tempfile::NamedTempFile;6use test_programs_artifacts::*;78macro_rules! assert_test_exists {9($name:ident) => {10#[expect(unused_imports, reason = "here to assert tests exist")]11use self::$name as _;12};13}14foreach_dwarf!(assert_test_exists);1516fn lldb_with_script(args: &[&str], script: &str) -> Result<String> {17let _ = env_logger::try_init();1819let lldb_path = env::var("LLDB").unwrap_or("lldb".to_string());20let mut cmd = Command::new(&lldb_path);2122cmd.arg("--batch");23if cfg!(target_os = "macos") {24cmd.args(&["-o", "settings set plugin.jit-loader.gdb.enable on"]);25}26let mut script_file = NamedTempFile::new()?;27script_file.write(script.as_bytes())?;28let script_path = script_file.path().to_str().unwrap();29cmd.args(&["-s", &script_path]);3031let mut me = std::env::current_exe().expect("current_exe specified");32me.pop(); // chop off the file name33me.pop(); // chop off `deps`34if cfg!(target_os = "windows") {35me.push("wasmtime.exe");36} else {37me.push("wasmtime");38}39cmd.arg(me);4041cmd.arg("--");42cmd.args(args);4344log::trace!("Running command: {cmd:?}");45let output = cmd.output().expect("success");4647let stdout = String::from_utf8(output.stdout)?;48log::trace!("--- sdout ---\n{stdout}");4950let stderr = String::from_utf8(output.stderr)?;51log::trace!("--- sderr ---\n{stderr}");5253if !output.status.success() {54bail!(55"failed to execute {cmd:?}:\n\56--- stderr ---\n\57{stderr}\n\58--- stdout ---\n\59{stdout}",60);61}62Ok(stdout)63}6465fn check_lldb_output(output: &str, directives: &str) -> Result<()> {66let mut builder = CheckerBuilder::new();67builder68.text(directives)69.map_err(|e| format_err!("unable to build checker: {e:?}"))?;70let checker = builder.finish();71let check = checker72.explain(output, NO_VARIABLES)73.map_err(|e| format_err!("{e:?}"))?;74assert!(check.0, "didn't pass check {}", check.1);75Ok(())76}7778#[allow(dead_code, reason = "tested elsewhere")]79fn dwarf_dead_code() {} // this is tested over in `translate.rs`8081#[test]82#[ignore]83pub fn dwarf_fib_wasm() -> Result<()> {84let output = lldb_with_script(85&[86"-Ccache=n",87"-Ddebug-info",88"-Oopt-level=0",89"--invoke",90"fib",91DWARF_FIB_WASM,92"3",93],94r#"b fib95r96fr v97c"#,98)?;99100check_lldb_output(101&output,102r#"103check: Breakpoint 1: no locations (pending)104check: Unable to resolve breakpoint to any actual locations.105check: 1 location added to breakpoint 1106check: stop reason = breakpoint 1.1107check: frame #0108sameln: JIT109sameln: fib(n=3)110check: n = 3111check: a = 0112check: resuming113check: exited with status114"#,115)?;116Ok(())117}118119#[test]120#[ignore]121pub fn dwarf_fib_wasm_dwarf5() -> Result<()> {122let output = lldb_with_script(123&[124"-Ccache=n",125"-Ddebug-info",126"-Oopt-level=0",127"--invoke",128"fib",129DWARF_FIB_WASM_DWARF5,130"3",131],132r#"b fib133r134fr v135c"#,136)?;137138check_lldb_output(139&output,140r#"141check: Breakpoint 1: no locations (pending)142check: Unable to resolve breakpoint to any actual locations.143check: 1 location added to breakpoint 1144check: stop reason = breakpoint 1.1145check: frame #0146sameln: JIT147sameln: fib(n=3)148check: n = 3149check: a = 0150check: resuming151check: exited with status152"#,153)?;154Ok(())155}156157#[test]158#[ignore]159pub fn dwarf_fib_wasm_split4() -> Result<()> {160let output = lldb_with_script(161&[162"-Ccache=n",163"-Ddebug-info",164"-Oopt-level=0",165"--invoke",166"fib",167DWARF_FIB_WASM_SPLIT4,168"3",169],170r#"b fib171r172fr v173c"#,174)?;175176check_lldb_output(177&output,178r#"179check: Breakpoint 1: no locations (pending)180check: Unable to resolve breakpoint to any actual locations.181check: 1 location added to breakpoint 1182check: stop reason = breakpoint 1.1183check: frame #0184sameln: JIT185sameln: fib(n=3)186check: n = 3187check: a = 0188check: resuming189check: exited with status190"#,191)?;192Ok(())193}194195#[test]196#[ignore]197pub fn dwarf_generic() -> Result<()> {198let output = lldb_with_script(199&["-Ccache=n", "-Ddebug-info", "-Oopt-level=0", DWARF_GENERIC],200r#"br set -n debug_break -C up201r202p __vmctx->set()203p (x + x)204c205p (x + x)206c207p inst.BaseValue + inst.DerivedValue208c209type lookup DerivedType210c211p __this->BaseValue + __this->DerivedValue212c213p __this->BaseValue + __this->DerivedValue214c215p __this->BaseValue + __this->DerivedValue216c217f218n219s220v var0221v var1222c"#,223)?;224225check_lldb_output(226&output,227r#"228check: stop reason = breakpoint 1.1229check: 2230check: stop reason = breakpoint 1.1231check: 4232check: stop reason = breakpoint 1.1233check: 3234check: stop reason = breakpoint 1.1235check: static int InstanceMethod236check: static int ConstInstanceMethod237check: stop reason = breakpoint 1.1238check: 6239check: stop reason = breakpoint 1.1240check: 7241check: stop reason = breakpoint 1.1242check: 8243check: stop reason = breakpoint 1.1244check: 9245check: 10246check: exited with status = 0247"#,248)?;249Ok(())250}251252#[test]253#[ignore]254pub fn dwarf_codegen_optimized() -> Result<()> {255let output = lldb_with_script(256&[257"-Ccache=n",258"-Ddebug-info",259"-Oopt-level=2",260DWARF_CODEGEN_OPTIMIZED,261],262r#"b InitializeTest263r264b dwarf_codegen_optimized.cc:25265b dwarf_codegen_optimized.cc:26266c267v x268c269v x270c"#,271)?;272273check_lldb_output(274&output,275r#"276check: stop reason = breakpoint 1.1277check: stop reason = breakpoint 2.1278check: x = 42279check: stop reason = breakpoint 3.1280check: x = <variable not available>281check: exited with status = 0282"#,283)?;284Ok(())285}286287#[test]288#[ignore]289pub fn dwarf_codegen_optimized_wasm_optimized() -> Result<()> {290let output = lldb_with_script(291&[292"-Ccache=n",293"-Ddebug-info",294"-Oopt-level=2",295DWARF_CODEGEN_OPTIMIZED_WASM_OPTIMIZED,296],297r#"b InitializeTest298r299b dwarf_codegen_optimized_wasm_optimized.cc:23300b dwarf_codegen_optimized_wasm_optimized.cc:29301c302v b303c304v b305c"#,306)?;307308check_lldb_output(309&output,310r#"311check: stop reason = breakpoint 1.1312check: stop reason = breakpoint 2.1313check: b = 42314check: stop reason = breakpoint 3.1315check: b = 43316check: exited with status = 0317"#,318)?;319Ok(())320}321322#[test]323#[ignore]324pub fn dwarf_fraction_norm() -> Result<()> {325let output = lldb_with_script(326&[327"-Ccache=n",328"-Oopt-level=0",329"-Ddebug-info",330DWARF_FRACTION_NORM,331],332r#"b dwarf_fraction_norm.cc:26333r334p __vmctx->set(),n->denominator335c"#,336)?;337338check_lldb_output(339&output,340r#"341check: Breakpoint 1: no locations (pending)342check: stop reason = breakpoint 1.1343check: frame #0344sameln: norm(n=(__ptr =345check: 27346check: resuming347"#,348)?;349Ok(())350}351352#[test]353#[ignore]354pub fn dwarf_two_removed_branches() -> Result<()> {355let output = lldb_with_script(356&[357"-Ccache=n",358"-Oopt-level=0",359"-Ddebug-info",360DWARF_TWO_REMOVED_BRANCHES,361],362r#"r"#,363)?;364365// We are simply checking that the output compiles.366check_lldb_output(367&output,368r#"369check: exited with status370"#,371)?;372Ok(())373}374375#[test]376#[ignore]377pub fn dwarf_spilled_frame_base() -> Result<()> {378let output = lldb_with_script(379&[380"-Ccache=n",381"-Oopt-level=0",382"-Ddebug-info",383DWARF_SPILLED_FRAME_BASE,384],385r#"b dwarf_spilled_frame_base.c:13386r387fr v i388n389fr v i390n391fr v i392n393fr v i394n395fr v i396n397fr v i398c399"#,400)?;401402// Check that if the frame base (shadow frame pointer) local403// is spilled, we can still read locals that reference it.404check_lldb_output(405&output,406r#"407check: i = 0408check: i = 1409check: i = 1410check: i = 1411check: i = 1412check: i = 1413check: exited with status414"#,415)?;416Ok(())417}418419#[test]420#[ignore]421pub fn dwarf_fission() -> Result<()> {422let output = lldb_with_script(423&["-Ccache=n", "-Ddebug-info", "-Oopt-level=0", DWARF_FISSION],424r#"breakpoint set --file dwarf_fission.c --line 8425r426fr v427s428fr v429c"#,430)?;431432check_lldb_output(433&output,434r#"435check: Breakpoint 1: no locations (pending)436check: Unable to resolve breakpoint to any actual locations.437check: 1 location added to breakpoint 1438check: stop reason = breakpoint 1.1439check: i = 1440check: stop reason = step in441check: i = 2442check: resuming443check: exited with status = 0444"#,445)?;446Ok(())447}448449fn test_dwarf_simple(wasm: &str, extra_args: &[&str]) -> Result<()> {450println!("testing {wasm:?}");451let mut args = vec![452"-Ccache=n",453"-Oopt-level=0",454"-Ddebug-info",455"-Wshared-memory",456];457args.extend(extra_args);458args.push(wasm);459let output = lldb_with_script(460&args,461r#"462breakpoint set --file dwarf_simple.rs --line 3463breakpoint set --file dwarf_simple.rs --line 5464r465fr v466c467fr v468breakpoint disable 2469c"#,470)?;471472check_lldb_output(473&output,474r#"475check: Breakpoint 1: no locations (pending)476check: Unable to resolve breakpoint to any actual locations.477check: 1 location added to breakpoint 1478check: stop reason = breakpoint 1.1479check: dwarf_simple.rs:3480check: a = 100481check: dwarf_simple.rs:5482check: a = 110483check: b = 117484check: resuming485check: exited with status = 0486"#,487)?;488Ok(())489}490491#[test]492#[ignore]493fn dwarf_simple() -> Result<()> {494for wasm in [DWARF_SIMPLE, DWARF_SIMPLE_COMPONENT] {495test_dwarf_simple(wasm, &[])?;496}497Ok(())498}499500#[test]501#[ignore]502fn dwarf_imported_memory() -> Result<()> {503test_dwarf_simple(504DWARF_IMPORTED_MEMORY,505&["--preload=env=./tests/all/native_debug/satisfy_memory_import.wat"],506)507}508509#[test]510#[ignore]511fn dwarf_shared_memory() -> Result<()> {512test_dwarf_simple(DWARF_SHARED_MEMORY, &[])513}514515#[test]516#[ignore]517fn dwarf_multiple_codegen_units() -> Result<()> {518for wasm in [519DWARF_MULTIPLE_CODEGEN_UNITS,520DWARF_MULTIPLE_CODEGEN_UNITS_COMPONENT,521] {522println!("testing {wasm:?}");523let output = lldb_with_script(524&["-Ccache=n", "-Oopt-level=0", "-Ddebug-info", wasm],525r#"526breakpoint set --file dwarf_multiple_codegen_units.rs --line 3527breakpoint set --file dwarf_multiple_codegen_units.rs --line 10528r529fr v530c531fr v532breakpoint delete 2533finish534c"#,535)?;536537check_lldb_output(538&output,539r#"540check: Breakpoint 1: no locations (pending)541check: Breakpoint 2: no locations (pending)542check: stop reason = breakpoint 1.1543check: foo::bar(a)544check: a = 3545check: sum += i546check: x = 3547check: sum = 0548check: 1 breakpoints deleted549check: Return value: $(=.*) 3550check: exited with status = 0551"#,552)?;553}554Ok(())555}556557558