Skip to content

Commit

Permalink
demo for capturing coverage data from inside market actor
Browse files Browse the repository at this point in the history
  • Loading branch information
dtynn committed Feb 12, 2022
1 parent 41d9150 commit b682aeb
Show file tree
Hide file tree
Showing 16 changed files with 168 additions and 10 deletions.
7 changes: 4 additions & 3 deletions actors/market/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ default = []
# This feature is set when building wasm
runtime-wasm = ["actors-runtime/runtime-wasm"]

wasm-prof = ["actors-runtime/wasm-prof"]

[build-dependencies]
wasm-builder = "3.0.1"


wasm-builder = { git = "https://github.com/paritytech/substrate.git", rev = "0a92e3e", package = "substrate-wasm-builder" }
# wasm-builder = { path = "/home/dtynn/proj/github.com/paritytech/substrate/utils/wasm-builder", package = "substrate-wasm-builder" }
# wasm-builder = "3.0.1"
26 changes: 22 additions & 4 deletions actors/market/build.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,30 @@
fn main() {
use wasm_builder::WasmBuilder;

#[cfg(not(feature = "wasm-prof"))]
WasmBuilder::new()
.with_current_project()
.import_memory()
.append_to_rust_flags("-Ctarget-feature=+crt-static")
.append_to_rust_flags("-Cpanic=abort")
.append_to_rust_flags("-Coverflow-checks=true")
.append_to_rust_flags("-Clto=true")
.append_to_rust_flags("-Coverflow-checks=yes")
.append_to_rust_flags("-Clto=yes")
.append_to_rust_flags("-Copt-level=z")
.build()
.build();

#[cfg(feature = "wasm-prof")]
std::env::set_var("WASM_BUILD_TYPE", "debug");

#[cfg(feature = "wasm-prof")]
WasmBuilder::new()
.with_current_project()
.append_to_rust_flags("-Ctarget-feature=+crt-static")
.append_to_rust_flags("-Cpanic=abort")
.append_to_rust_flags("-Coverflow-checks=yes")
.append_to_rust_flags("--emit=llvm-ir")
.append_to_rust_flags("-Zinstrument-coverage")
.append_to_rust_flags("-Zno-profiler-runtime")
.append_to_rust_flags("-Ccodegen-units=1")
.append_to_rust_flags("-Copt-level=0")
.append_to_rust_flags("-Clink-dead-code")
.build();
}
1 change: 1 addition & 0 deletions actors/runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ default = []
devnet = []
interopnet = []
test_utils = ["hex"]
wasm-prof = ["fvm_sdk/wasm-prof"]

# This feature is set when building wasm
runtime-wasm = ["fvm_sdk"]
Expand Down
10 changes: 9 additions & 1 deletion actors/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,15 @@ macro_rules! wasm_trampoline {
#[no_mangle]
#[cfg(feature = "runtime-wasm")]
pub extern "C" fn invoke(param: u32) -> u32 {
$crate::runtime::fvm::trampoline::<$target>(param)
#[cfg(feature = "wasm-prof")]
$crate::runtime::fvm::prof::reset_coverage();

let ret = $crate::runtime::fvm::trampoline::<$target>(param);

#[cfg(feature = "wasm-prof")]
let _ = $crate::runtime::fvm::prof::capture_coverage();

ret
}
};
}
Expand Down
3 changes: 3 additions & 0 deletions actors/runtime/src/runtime/fvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ lazy_static! {
};
}

#[cfg(feature = "wasm-prof")]
pub use fvm::prof;

/// A runtime that bridges to the FVM environment through the FVM SDK.
pub struct FvmRuntime<B = ActorBlockstore> {
blockstore: B,
Expand Down
5 changes: 4 additions & 1 deletion fvm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,7 @@ builtin_actors = [
"fvm_actor_reward",
"fvm_actor_system",
"fvm_actor_verifreg"
]
]
wasm-prof = [
"fvm_actor_market/wasm-prof",
]
2 changes: 2 additions & 0 deletions fvm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ mod blockstore;
mod market_actor;
mod power_actor;

pub use fvm_actor_market;

#[derive(Clone)]
pub struct Config {
/// The maximum call depth.
Expand Down
6 changes: 6 additions & 0 deletions fvm/src/syscalls/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ mod send;
mod sself;
mod vm;

#[cfg(feature = "wasm-prof")]
mod prof;

pub(self) use context::Context;

/// Invocation data attached to a wasm "store" and available to the syscall binding.
Expand Down Expand Up @@ -116,6 +119,9 @@ pub fn bind_syscalls(
linker.bind("debug", "log", debug::log)?;
linker.bind("debug", "enabled", debug::enabled)?;

#[cfg(feature = "wasm-prof")]
linker.bind("prof", "capture_coverage", prof::capture_coverage)?;

Ok(())
}

Expand Down
15 changes: 15 additions & 0 deletions fvm/src/syscalls/prof.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use super::Context;
use crate::kernel::{Kernel, Result};

pub fn capture_coverage(
context: Context<'_, impl Kernel>,
data_off: u32,
data_len: u32,
) -> Result<()> {
let data = context.memory.try_slice(data_off, data_len)?;

println!("get coverage data, size={} B", data.len());
std::fs::write("cov.profraw", data).expect("write cov prof raw data");

Ok(())
}
5 changes: 5 additions & 0 deletions sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,8 @@ num-traits = { version = "0.2.14", default-features = false }
lazy_static = "1.4.0"
log = "0.4.14"
thiserror = "1.0.30"
minicov = { version = "0.2.2", optional = true }

[features]
default = []
wasm-prof = ["minicov"]
3 changes: 3 additions & 0 deletions sdk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ pub mod sself;
pub mod sys;
pub mod vm;

#[cfg(feature = "wasm-prof")]
pub mod prof;

/// The maximum supported CID size. (SPEC_AUDIT)
pub const MAX_CID_LEN: usize = 100;

Expand Down
15 changes: 15 additions & 0 deletions sdk/src/prof.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use crate::{sys, SyscallResult};

pub fn reset_coverage() {
minicov::reset_coverage();
}

pub fn capture_coverage() -> SyscallResult<()> {
let data = minicov::capture_coverage();

unsafe {
sys::prof::capture_coverage(data.as_ptr(), data.len() as u32)?;
}

Ok(())
}
3 changes: 3 additions & 0 deletions sdk/src/sys/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ pub mod send;
pub mod sself;
pub mod vm;

#[cfg(feature = "wasm-prof")]
pub mod prof;

/// Generate a set of FVM syscall shims.
///
/// ```ignore
Expand Down
5 changes: 5 additions & 0 deletions sdk/src/sys/prof.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
super::fvm_syscalls! {
module = "prof";

pub fn capture_coverage(data_off: *const u8, data_len: u32) -> Result<()>;
}
9 changes: 8 additions & 1 deletion testing/conformance/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ ittapi-rs = { version = "0.1.6", optional = true }

[features]
vtune = ["wasmtime/vtune", "ittapi-rs"]
wasm-prof = ["fvm/wasm-prof"]

[dev-dependencies]
pretty_env_logger = "0.4.0"
Expand All @@ -55,10 +56,16 @@ test = false
bench = false
required-features = ["vtune"]

[[bin]]
name = "coverage-conformance"
test = false
bench = false
required-features = ["wasm-prof"]

[[bench]]
name = "bench_conformance"
harness = false

[[bench]]
name = "bench_conformance_overhead"
harness = false
harness = false
63 changes: 63 additions & 0 deletions testing/conformance/src/bin/coverage-conformance.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
use std::env;
use std::path::PathBuf;

use conformance_tests::vector::{MessageVector, Selector, Variant};
use conformance_tests::vm::{TestKernel, TestMachine};
use fvm::executor::{ApplyKind, DefaultExecutor, Executor};
use fvm::machine::Engine;
use fvm_shared::address::Protocol;
use fvm_shared::blockstore::MemoryBlockstore;
use fvm_shared::crypto::signature::SECP_SIG_LEN;
use fvm_shared::encoding::Cbor;
use fvm_shared::message::Message;
// use wasmtime::{Engine, Module};

pub fn main() {
println!("good");

// let binary = fvm::fvm_actor_market::wasm::WASM_BINARY_BLOATY.expect("get binary");
// let binary = fvm::fvm_actor_market::wasm::WASM_BINARY.expect("get binary");
// std::fs::write("actor_market.wasm", binary).expect("write binary");

// let engine = Engine::default();
// let module = Module::from_binary(&engine, binary).expect("load wasm");

let vec_path = env::var("VECTOR")
.map(|s| PathBuf::from(s))
.expect("get vector path from env");

let vector = MessageVector::from_file(&vec_path).expect("construct MessageVector");

let skip = !vector.selector.as_ref().map_or(true, Selector::supported);
if skip {
println!("skipping because selector not supported");
return;
}

let engine = Engine::default();

let (bs, _) = async_std::task::block_on(vector.seed_blockstore()).unwrap();

for variant in vector.preconditions.variants.iter().take(1) {
let machine = TestMachine::new_for_vector(&vector, variant, bs.clone(), engine.clone());
let mut exec: DefaultExecutor<TestKernel> = DefaultExecutor::new(machine);

for m in vector.apply_messages.iter() {
let msg = Message::unmarshal_cbor(&m.bytes).unwrap();

// Execute the message.
let mut raw_length = m.bytes.len();
if msg.from.protocol() == Protocol::Secp256k1 {
// 65 bytes signature + 1 byte type + 3 bytes for field info.
raw_length += SECP_SIG_LEN + 4;
}

unsafe {
exec.execute_message(msg, ApplyKind::Explicit, raw_length)
.expect("failed to execute a message");
}
}
}

println!("done");
}

0 comments on commit b682aeb

Please sign in to comment.