rbpf-cli: only run static analysis when needed (#23110)

This commit is contained in:
Richard Patel 2022-02-16 03:35:05 +01:00 committed by GitHub
parent 64f5e57666
commit 56e23432b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 35 additions and 6 deletions

View File

@ -273,17 +273,20 @@ native machine code before execting it in the virtual machine.",
check(text_bytes, &config).unwrap(); check(text_bytes, &config).unwrap();
} }
Executable::<BpfError, ThisInstructionMeter>::jit_compile(&mut executable).unwrap(); Executable::<BpfError, ThisInstructionMeter>::jit_compile(&mut executable).unwrap();
let analysis = Analysis::from_executable(&executable); let mut analysis = LazyAnalysis::new(&executable);
match matches.value_of("use") { match matches.value_of("use") {
Some("cfg") => { Some("cfg") => {
let mut file = File::create("cfg.dot").unwrap(); let mut file = File::create("cfg.dot").unwrap();
analysis.visualize_graphically(&mut file, None).unwrap(); analysis
.analyze()
.visualize_graphically(&mut file, None)
.unwrap();
return; return;
} }
Some("disassembler") => { Some("disassembler") => {
let stdout = std::io::stdout(); let stdout = std::io::stdout();
analysis.disassemble(&mut stdout.lock()).unwrap(); analysis.analyze().disassemble(&mut stdout.lock()).unwrap();
return; return;
} }
_ => {} _ => {}
@ -325,13 +328,15 @@ native machine code before execting it in the virtual machine.",
if matches.is_present("trace") { if matches.is_present("trace") {
eprintln!("Trace is saved in trace.out"); eprintln!("Trace is saved in trace.out");
let mut file = File::create("trace.out").unwrap(); let mut file = File::create("trace.out").unwrap();
let analysis = Analysis::from_executable(&executable); vm.get_tracer()
vm.get_tracer().write(&mut file, &analysis).unwrap(); .write(&mut file, analysis.analyze())
.unwrap();
} }
if matches.is_present("profile") { if matches.is_present("profile") {
eprintln!("Profile is saved in profile.dot"); eprintln!("Profile is saved in profile.dot");
let tracer = &vm.get_tracer(); let tracer = &vm.get_tracer();
let dynamic_analysis = DynamicAnalysis::new(tracer, &analysis); let analysis = analysis.analyze();
let dynamic_analysis = DynamicAnalysis::new(tracer, analysis);
let mut file = File::create("profile.dot").unwrap(); let mut file = File::create("profile.dot").unwrap();
analysis analysis
.visualize_graphically(&mut file, Some(&dynamic_analysis)) .visualize_graphically(&mut file, Some(&dynamic_analysis))
@ -354,3 +359,27 @@ impl Debug for Output {
Ok(()) Ok(())
} }
} }
// Replace with std::lazy::Lazy when stabilized.
// https://github.com/rust-lang/rust/issues/74465
struct LazyAnalysis<'a> {
analysis: Option<Analysis<'a, BpfError, ThisInstructionMeter>>,
executable: &'a Executable<BpfError, ThisInstructionMeter>,
}
impl<'a> LazyAnalysis<'a> {
fn new(executable: &'a Executable<BpfError, ThisInstructionMeter>) -> Self {
Self {
analysis: None,
executable,
}
}
fn analyze(&mut self) -> &Analysis<BpfError, ThisInstructionMeter> {
if let Some(ref analysis) = self.analysis {
return analysis;
}
self.analysis
.insert(Analysis::from_executable(self.executable))
}
}