Move most wasmtime tests into one test suite (#1544)
* Move most wasmtime tests into one test suite This commit moves most wasmtime tests into a single test suite which gets compiled into one executable instead of having lots of test executables. The goal here is to reduce disk space on CI, and this should be achieved by having fewer executables which means fewer copies of `libwasmtime.rlib` linked across binaries on the system. More importantly though this means that DWARF debug information should only be in one executable rather than duplicated across many. * Share more build caches Globally set `RUSTFLAGS` to `-Dwarnings` instead of individually so all build steps share the same value. * Allow some dead code in cranelift-codegen Prevents having to fix all warnings for all possible feature combinations, only the main ones which come up. * Update some debug file paths
This commit is contained in:
30
tests/all/debug/dump.rs
Normal file
30
tests/all/debug/dump.rs
Normal file
@@ -0,0 +1,30 @@
|
||||
use anyhow::{bail, Result};
|
||||
use std::env;
|
||||
use std::process::Command;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[allow(dead_code)]
|
||||
pub enum DwarfDumpSection {
|
||||
DebugInfo,
|
||||
DebugLine,
|
||||
}
|
||||
|
||||
pub fn get_dwarfdump(obj: &str, section: DwarfDumpSection) -> Result<String> {
|
||||
let dwarfdump = env::var("DWARFDUMP").unwrap_or("llvm-dwarfdump".to_string());
|
||||
let section_flag = match section {
|
||||
DwarfDumpSection::DebugInfo => "-debug-info",
|
||||
DwarfDumpSection::DebugLine => "-debug-line",
|
||||
};
|
||||
let output = Command::new(&dwarfdump)
|
||||
.args(&[section_flag, obj])
|
||||
.output()
|
||||
.expect("success");
|
||||
if !output.status.success() {
|
||||
bail!(
|
||||
"failed to execute {}: {}",
|
||||
dwarfdump,
|
||||
String::from_utf8_lossy(&output.stderr),
|
||||
);
|
||||
}
|
||||
Ok(String::from_utf8_lossy(&output.stdout).to_string())
|
||||
}
|
||||
128
tests/all/debug/lldb.rs
Normal file
128
tests/all/debug/lldb.rs
Normal file
@@ -0,0 +1,128 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use anyhow::{bail, format_err, Result};
|
||||
use filecheck::{CheckerBuilder, NO_VARIABLES};
|
||||
use std::env;
|
||||
use std::io::Write;
|
||||
use std::process::Command;
|
||||
use tempfile::NamedTempFile;
|
||||
|
||||
fn lldb_with_script(args: &[&str], script: &str) -> Result<String> {
|
||||
let lldb_path = env::var("LLDB").unwrap_or("lldb".to_string());
|
||||
let mut cmd = Command::new(&lldb_path);
|
||||
|
||||
cmd.arg("--batch");
|
||||
if cfg!(target_os = "macos") {
|
||||
cmd.args(&["-o", "settings set plugin.jit-loader.gdb.enable on"]);
|
||||
}
|
||||
let mut script_file = NamedTempFile::new()?;
|
||||
script_file.write(script.as_bytes())?;
|
||||
let script_path = script_file.path().to_str().unwrap();
|
||||
cmd.args(&["-s", &script_path]);
|
||||
|
||||
let mut me = std::env::current_exe().expect("current_exe specified");
|
||||
me.pop(); // chop off the file name
|
||||
me.pop(); // chop off `deps`
|
||||
me.push("wasmtime");
|
||||
cmd.arg(me);
|
||||
|
||||
cmd.arg("--");
|
||||
cmd.args(args);
|
||||
|
||||
let output = cmd.output().expect("success");
|
||||
if !output.status.success() {
|
||||
bail!(
|
||||
"failed to execute {:?}: {}",
|
||||
cmd,
|
||||
String::from_utf8_lossy(&output.stderr),
|
||||
);
|
||||
}
|
||||
Ok(String::from_utf8(output.stdout)?)
|
||||
}
|
||||
|
||||
fn check_lldb_output(output: &str, directives: &str) -> Result<()> {
|
||||
let mut builder = CheckerBuilder::new();
|
||||
builder
|
||||
.text(directives)
|
||||
.map_err(|e| format_err!("unable to build checker: {:?}", e))?;
|
||||
let checker = builder.finish();
|
||||
let check = checker
|
||||
.explain(output, NO_VARIABLES)
|
||||
.map_err(|e| format_err!("{:?}", e))?;
|
||||
assert!(check.0, "didn't pass check {}", check.1);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
#[cfg(all(
|
||||
any(target_os = "linux", target_os = "macos"),
|
||||
target_pointer_width = "64"
|
||||
))]
|
||||
pub fn test_debug_dwarf_lldb() -> Result<()> {
|
||||
let output = lldb_with_script(
|
||||
&[
|
||||
"-g",
|
||||
"tests/all/debug/testsuite/fib-wasm.wasm",
|
||||
"--invoke",
|
||||
"fib",
|
||||
"3",
|
||||
],
|
||||
r#"b fib
|
||||
r
|
||||
fr v
|
||||
c"#,
|
||||
)?;
|
||||
|
||||
check_lldb_output(
|
||||
&output,
|
||||
r#"
|
||||
check: Breakpoint 1: no locations (pending)
|
||||
check: Unable to resolve breakpoint to any actual locations.
|
||||
check: 1 location added to breakpoint 1
|
||||
check: stop reason = breakpoint 1.1
|
||||
check: frame #0
|
||||
sameln: JIT
|
||||
sameln: fib(n=3)
|
||||
check: n = 3
|
||||
check: a = 0
|
||||
check: resuming
|
||||
check: exited with status
|
||||
"#,
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
#[cfg(all(
|
||||
any(target_os = "linux", target_os = "macos"),
|
||||
target_pointer_width = "64"
|
||||
))]
|
||||
pub fn test_debug_dwarf_ptr() -> Result<()> {
|
||||
let output = lldb_with_script(
|
||||
&[
|
||||
"-g",
|
||||
"--opt-level",
|
||||
"0",
|
||||
"tests/all/debug/testsuite/reverse-str.wasm",
|
||||
],
|
||||
r#"b reverse-str.c:9
|
||||
r
|
||||
p __vmctx->set(),&*s
|
||||
c"#,
|
||||
)?;
|
||||
|
||||
check_lldb_output(
|
||||
&output,
|
||||
r#"
|
||||
check: Breakpoint 1: no locations (pending)
|
||||
check: stop reason = breakpoint 1.1
|
||||
check: frame #0
|
||||
sameln: reverse(s=(__ptr =
|
||||
check: "Hello, world."
|
||||
check: resuming
|
||||
"#,
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
5
tests/all/debug/mod.rs
Normal file
5
tests/all/debug/mod.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
mod dump;
|
||||
mod lldb;
|
||||
mod obj;
|
||||
mod simulate;
|
||||
mod translate;
|
||||
34
tests/all/debug/obj.rs
Normal file
34
tests/all/debug/obj.rs
Normal file
@@ -0,0 +1,34 @@
|
||||
use anyhow::{Context as _, Result};
|
||||
use std::fs::File;
|
||||
use std::path::Path;
|
||||
use target_lexicon::Triple;
|
||||
use wasmtime::Strategy;
|
||||
use wasmtime_cli::compile_to_obj;
|
||||
use wasmtime_environ::CacheConfig;
|
||||
|
||||
pub fn compile_cranelift(
|
||||
wasm: &[u8],
|
||||
target: Option<Triple>,
|
||||
output: impl AsRef<Path>,
|
||||
) -> Result<()> {
|
||||
let obj = compile_to_obj(
|
||||
wasm,
|
||||
target.as_ref(),
|
||||
Strategy::Cranelift,
|
||||
false,
|
||||
wasmtime::OptLevel::None,
|
||||
true,
|
||||
output
|
||||
.as_ref()
|
||||
.file_name()
|
||||
.unwrap()
|
||||
.to_string_lossy()
|
||||
.to_string(),
|
||||
&CacheConfig::new_cache_disabled(),
|
||||
)?;
|
||||
|
||||
let file = File::create(output).context("failed to create object file")?;
|
||||
obj.write(file).context("failed to write object file")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
99
tests/all/debug/simulate.rs
Normal file
99
tests/all/debug/simulate.rs
Normal file
@@ -0,0 +1,99 @@
|
||||
use super::dump::{get_dwarfdump, DwarfDumpSection};
|
||||
use super::obj::compile_cranelift;
|
||||
use anyhow::{format_err, Result};
|
||||
use filecheck::{CheckerBuilder, NO_VARIABLES};
|
||||
use tempfile::NamedTempFile;
|
||||
use wat::parse_str;
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn check_wat(wat: &str) -> Result<()> {
|
||||
let wasm = parse_str(wat)?;
|
||||
let obj_file = NamedTempFile::new()?;
|
||||
let obj_path = obj_file.path().to_str().unwrap();
|
||||
compile_cranelift(&wasm, None, obj_path)?;
|
||||
let dump = get_dwarfdump(obj_path, DwarfDumpSection::DebugInfo)?;
|
||||
let mut builder = CheckerBuilder::new();
|
||||
builder
|
||||
.text(wat)
|
||||
.map_err(|e| format_err!("unable to build checker: {:?}", e))?;
|
||||
let checker = builder.finish();
|
||||
let check = checker
|
||||
.explain(&dump, NO_VARIABLES)
|
||||
.map_err(|e| format_err!("{:?}", e))?;
|
||||
assert!(check.0, "didn't pass check {}", check.1);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
#[cfg(all(
|
||||
any(target_os = "linux", target_os = "macos"),
|
||||
target_pointer_width = "64"
|
||||
))]
|
||||
fn test_debug_dwarf_simulate_simple_x86_64() -> Result<()> {
|
||||
check_wat(
|
||||
r#"
|
||||
;; check: DW_TAG_compile_unit
|
||||
(module
|
||||
;; check: DW_TAG_subprogram
|
||||
;; check: DW_AT_name ("wasm-function[0]")
|
||||
;; check: DW_TAG_formal_parameter
|
||||
;; check: DW_AT_name ("var0")
|
||||
;; check: DW_AT_type
|
||||
;; sameln: "i32"
|
||||
;; check: DW_TAG_variable
|
||||
;; check: DW_AT_name ("var1")
|
||||
;; check: DW_AT_type
|
||||
;; sameln: "i32"
|
||||
(func (param i32) (result i32)
|
||||
(local i32)
|
||||
local.get 0
|
||||
local.set 1
|
||||
local.get 1
|
||||
)
|
||||
)"#,
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
#[cfg(all(
|
||||
any(target_os = "linux", target_os = "macos"),
|
||||
target_pointer_width = "64"
|
||||
))]
|
||||
fn test_debug_dwarf_simulate_with_imports_x86_64() -> Result<()> {
|
||||
check_wat(
|
||||
r#"
|
||||
;; check: DW_TAG_compile_unit
|
||||
(module
|
||||
;; check: DW_TAG_subprogram
|
||||
;; check: DW_AT_name ("func1")
|
||||
(import "foo" "bar" (func $import1) )
|
||||
(func $func1 (result i32)
|
||||
i32.const 1
|
||||
)
|
||||
)"#,
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
#[cfg(all(
|
||||
any(target_os = "linux", target_os = "macos"),
|
||||
target_pointer_width = "64"
|
||||
))]
|
||||
fn test_debug_dwarf_simulate_with_invalid_name_x86_64() -> Result<()> {
|
||||
check_wat(
|
||||
r#"
|
||||
;; check: DW_TAG_compile_unit
|
||||
(module (@name "\00")
|
||||
;; check: DW_TAG_subprogram
|
||||
;; check: DW_AT_name ("wasm-function[1]")
|
||||
(import "foo" "bar" (func $import1) )
|
||||
(func (@name "\00f") (result i32)
|
||||
(local (@name "l\00") i32)
|
||||
i32.const 1
|
||||
)
|
||||
)"#,
|
||||
)
|
||||
}
|
||||
13
tests/all/debug/testsuite/fib-wasm.c
Normal file
13
tests/all/debug/testsuite/fib-wasm.c
Normal file
@@ -0,0 +1,13 @@
|
||||
// Compile with:
|
||||
// clang --target=wasm32 fib-wasm.c -o fib-wasm.wasm -g \
|
||||
// -Wl,--no-entry,--export=fib -nostdlib -fdebug-prefix-map=$PWD=.
|
||||
|
||||
int fib(int n) {
|
||||
int i, t, a = 0, b = 1;
|
||||
for (i = 0; i < n; i++) {
|
||||
t = a;
|
||||
a = b;
|
||||
b += t;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
BIN
tests/all/debug/testsuite/fib-wasm.wasm
Executable file
BIN
tests/all/debug/testsuite/fib-wasm.wasm
Executable file
Binary file not shown.
21
tests/all/debug/testsuite/reverse-str.c
Normal file
21
tests/all/debug/testsuite/reverse-str.c
Normal file
@@ -0,0 +1,21 @@
|
||||
// Compile with:
|
||||
// clang --target=wasm32 reverse-str.c -o reverse-str.wasm -g \
|
||||
// -O0 -nostdlib -fdebug-prefix-map=$PWD=.
|
||||
#include <stdlib.h>
|
||||
|
||||
void reverse(char *s, size_t len)
|
||||
{
|
||||
if (!len) return;
|
||||
size_t i = 0, j = len - 1;
|
||||
while (i < j) {
|
||||
char t = s[i];
|
||||
s[i++] = s[j];
|
||||
s[j--] = t;
|
||||
}
|
||||
}
|
||||
|
||||
void _start()
|
||||
{
|
||||
char hello[] = "Hello, world.";
|
||||
reverse(hello, 13);
|
||||
}
|
||||
BIN
tests/all/debug/testsuite/reverse-str.wasm
Executable file
BIN
tests/all/debug/testsuite/reverse-str.wasm
Executable file
Binary file not shown.
57
tests/all/debug/translate.rs
Normal file
57
tests/all/debug/translate.rs
Normal file
@@ -0,0 +1,57 @@
|
||||
use super::dump::{get_dwarfdump, DwarfDumpSection};
|
||||
use super::obj::compile_cranelift;
|
||||
use anyhow::{format_err, Result};
|
||||
use filecheck::{CheckerBuilder, NO_VARIABLES};
|
||||
use std::fs::read;
|
||||
use tempfile::NamedTempFile;
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn check_wasm(wasm_path: &str, directives: &str) -> Result<()> {
|
||||
let wasm = read(wasm_path)?;
|
||||
let obj_file = NamedTempFile::new()?;
|
||||
let obj_path = obj_file.path().to_str().unwrap();
|
||||
compile_cranelift(&wasm, None, obj_path)?;
|
||||
let dump = get_dwarfdump(obj_path, DwarfDumpSection::DebugInfo)?;
|
||||
let mut builder = CheckerBuilder::new();
|
||||
builder
|
||||
.text(directives)
|
||||
.map_err(|e| format_err!("unable to build checker: {:?}", e))?;
|
||||
let checker = builder.finish();
|
||||
let check = checker
|
||||
.explain(&dump, NO_VARIABLES)
|
||||
.map_err(|e| format_err!("{:?}", e))?;
|
||||
assert!(check.0, "didn't pass check {}", check.1);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
#[cfg(all(
|
||||
any(target_os = "linux", target_os = "macos"),
|
||||
target_pointer_width = "64"
|
||||
))]
|
||||
fn test_debug_dwarf_translate() -> Result<()> {
|
||||
check_wasm(
|
||||
"tests/all/debug/testsuite/fib-wasm.wasm",
|
||||
r##"
|
||||
check: DW_TAG_compile_unit
|
||||
# We have "fib" function
|
||||
check: DW_TAG_subprogram
|
||||
check: DW_AT_name ("fib")
|
||||
# Accepts one parameter
|
||||
check: DW_TAG_formal_parameter
|
||||
check: DW_AT_name ("n")
|
||||
check: DW_AT_decl_line (5)
|
||||
# Has four locals: i, t, a, b
|
||||
check: DW_TAG_variable
|
||||
check: DW_AT_name ("i")
|
||||
check: DW_AT_decl_line (6)
|
||||
check: DW_TAG_variable
|
||||
check: DW_AT_name ("t")
|
||||
check: DW_TAG_variable
|
||||
check: DW_AT_name ("a")
|
||||
check: DW_TAG_variable
|
||||
check: DW_AT_name ("b")
|
||||
"##,
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user