From 8b3be39ba1a1d0685e6283175d7d9f951e9b8f3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20M=C3=BCller?= Date: Mon, 12 Jun 2023 10:51:39 -0700 Subject: [PATCH] Add more benchmarks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change adds three more benchmarks to our suite. The first one measures symbolization time using the ELF symbolizer, the second one using the DWARF symbolizer but without querying line information, and the third one is focused on inspection of an ELF file (i.e., by-name lookup). Compared to before, we make sure to actually generate an ELF file without DWARF information and a DWARF file without ELF symbols, respectively. Signed-off-by: Daniel Müller --- CHANGELOG.md | 6 ++++++ benches/inspect.rs | 24 ++++++++++++++++++++- benches/symbolize.rs | 51 +++++++++++++++++++++++++++++++++++++++++++- build.rs | 33 ++++++++++++++++++++-------- 4 files changed, 103 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7df19402..2e51d501 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +Unreleased +---------- +- Added additional end-to-end benchmarks + - Added benchmark result summary to CI runs + + 0.2.0-alpha.3 ------------- - Introduced custom `Error` type instead of relying solely on diff --git a/benches/inspect.rs b/benches/inspect.rs index 2559052b..d995fed2 100644 --- a/benches/inspect.rs +++ b/benches/inspect.rs @@ -8,12 +8,33 @@ use criterion::measurement::Measurement; use criterion::BenchmarkGroup; +/// Lookup an address in an ELF file, end-to-end, i.e., including all +/// necessary setup. +fn lookup_elf() { + let dwarf_vmlinux = Path::new(&env!("CARGO_MANIFEST_DIR")) + .join("data") + .join("vmlinux-5.17.12-100.fc34.x86_64.elf"); + let src = inspect::Source::Elf(inspect::Elf::new(dwarf_vmlinux)); + + let inspector = Inspector::new(); + let results = inspector + .lookup(black_box(&["abort_creds"]), black_box(&src)) + .unwrap() + .into_iter() + .flatten() + .collect::>(); + assert_eq!(results.len(), 1); + + let result = results.first().unwrap(); + assert_eq!(result.addr, 0xffffffff8110ecb0); +} + /// Lookup an address in a DWARF file, end-to-end, i.e., including all necessary /// setup. fn lookup_dwarf() { let dwarf_vmlinux = Path::new(&env!("CARGO_MANIFEST_DIR")) .join("data") - .join("vmlinux-5.17.12-100.fc34.x86_64"); + .join("vmlinux-5.17.12-100.fc34.x86_64.dwarf"); let src = inspect::Source::Elf(inspect::Elf::new(dwarf_vmlinux)); let inspector = Inspector::new(); @@ -35,5 +56,6 @@ where { if cfg!(feature = "generate-large-test-files") { bench_fn!(group, lookup_dwarf); + bench_fn!(group, lookup_elf); } } diff --git a/benches/symbolize.rs b/benches/symbolize.rs index 2e716c3d..c20c3cd1 100644 --- a/benches/symbolize.rs +++ b/benches/symbolize.rs @@ -32,12 +32,58 @@ fn symbolize_process() { assert_eq!(results.len(), addrs.len()); } +/// Symbolize an address in an ELF file, end-to-end, i.e., including all +/// necessary setup. +fn symbolize_elf() { + let elf_vmlinux = Path::new(&env!("CARGO_MANIFEST_DIR")) + .join("data") + .join("vmlinux-5.17.12-100.fc34.x86_64.elf"); + let src = Source::Elf(Elf::new(elf_vmlinux)); + let symbolizer = Symbolizer::builder() + .enable_debug_syms(false) + .enable_src_location(false) + .build(); + + let results = symbolizer + .symbolize(black_box(&src), black_box(&[0xffffffff8110ecb0])) + .unwrap() + .into_iter() + .flatten() + .collect::>(); + assert_eq!(results.len(), 1); + + let result = results.first().unwrap(); + assert_eq!(result.symbol, "abort_creds"); +} + +/// Symbolize an address in a DWARF file, excluding line information, +/// end-to-end, i.e., including all necessary setup. +fn symbolize_dwarf_no_lines() { + let dwarf_vmlinux = Path::new(&env!("CARGO_MANIFEST_DIR")) + .join("data") + .join("vmlinux-5.17.12-100.fc34.x86_64.dwarf"); + let src = Source::Elf(Elf::new(dwarf_vmlinux)); + let symbolizer = Symbolizer::builder().enable_src_location(false).build(); + + let results = symbolizer + .symbolize(black_box(&src), black_box(&[0xffffffff8110ecb0])) + .unwrap() + .into_iter() + .flatten() + .collect::>(); + assert_eq!(results.len(), 1); + + let result = results.first().unwrap(); + assert_eq!(result.symbol, "abort_creds"); + assert_eq!(result.line, 0); +} + /// Symbolize an address in a DWARF file, end-to-end, i.e., including all /// necessary setup. fn symbolize_dwarf() { let dwarf_vmlinux = Path::new(&env!("CARGO_MANIFEST_DIR")) .join("data") - .join("vmlinux-5.17.12-100.fc34.x86_64"); + .join("vmlinux-5.17.12-100.fc34.x86_64.dwarf"); let src = Source::Elf(Elf::new(dwarf_vmlinux)); let symbolizer = Symbolizer::new(); @@ -51,6 +97,7 @@ fn symbolize_dwarf() { let result = results.first().unwrap(); assert_eq!(result.symbol, "abort_creds"); + assert_eq!(result.line, 534); } /// Symbolize an address in a GSYM file, end-to-end, i.e., including all @@ -80,6 +127,8 @@ where { bench_fn!(group, symbolize_process); if cfg!(feature = "generate-large-test-files") { + bench_fn!(group, symbolize_elf); + bench_fn!(group, symbolize_dwarf_no_lines); bench_fn!(group, symbolize_dwarf); bench_fn!(group, symbolize_gsym); } diff --git a/build.rs b/build.rs index c0cec4fd..3af99a41 100644 --- a/build.rs +++ b/build.rs @@ -170,7 +170,7 @@ fn gsym(src: &Path, dst: impl AsRef) { } /// Invoke `strip` on a copy of `src` placed at `dst`. -fn strip(src: &Path, dst: &str, options: &[&str]) { +fn strip(src: &Path, dst: impl AsRef, options: &[&str]) { let dst = src.with_file_name(dst); println!("cargo:rerun-if-changed={}", src.display()); println!("cargo:rerun-if-changed={}", dst.display()); @@ -185,9 +185,15 @@ fn strip(src: &Path, dst: &str, options: &[&str]) { let () = adjust_mtime(&dst).unwrap(); } +/// Strip all DWARF information from an ELF binary, in an attempt to +/// leave only ELF symbols in place. +fn elf(src: &Path, dst: impl AsRef) { + strip(src, dst, &["--strip-debug"]) +} + /// Strip all non-debug information from an ELF binary, in an attempt to /// leave only DWARF remains. -fn dwarf(src: &Path, dst: &str) { +fn dwarf(src: &Path, dst: impl AsRef) { strip(src, dst, &["--keep-section=.debug_*"]) } @@ -408,19 +414,28 @@ fn download_bench_files(_crate_root: &Path) { /// Prepare benchmark files. fn prepare_bench_files(crate_root: &Path) { - let vmlinux = Path::new(crate_root) + let vmlinux_xz = Path::new(crate_root) .join("data") .join("vmlinux-5.17.12-100.fc34.x86_64.xz"); - let mut dst = vmlinux.clone(); - assert!(dst.set_extension("")); - unpack_xz(&vmlinux, &dst); + let mut vmlinux = vmlinux_xz.clone(); + assert!(vmlinux.set_extension("")); + unpack_xz(&vmlinux_xz, &vmlinux); - let src = dst.clone(); - let mut dst = vmlinux; + let mut dst = vmlinux_xz.clone(); + assert!(dst.set_extension("elf")); + let dst = dst.file_name().unwrap(); + elf(&vmlinux, dst); + + let mut dst = vmlinux_xz.clone(); assert!(dst.set_extension("gsym")); let dst = dst.file_name().unwrap(); - gsym(&src, dst); + gsym(&vmlinux, dst); + + let mut dst = vmlinux_xz; + assert!(dst.set_extension("dwarf")); + let dst = dst.file_name().unwrap(); + dwarf(&vmlinux, dst); } fn main() {