pyroscope_rbspy_oncpu/
lib.rs

1extern crate anyhow;
2#[cfg(test)]
3extern crate byteorder;
4extern crate chrono;
5extern crate clap;
6extern crate ctrlc;
7extern crate env_logger;
8extern crate inferno;
9extern crate libc;
10#[cfg(target_os = "macos")]
11extern crate libproc;
12#[cfg(unix)]
13extern crate nix;
14extern crate proc_maps;
15#[macro_use]
16extern crate log;
17extern crate rand;
18#[cfg(test)]
19extern crate rbspy_testdata;
20extern crate remoteprocess;
21
22extern crate rbspy_ruby_structs as bindings;
23extern crate serde;
24#[macro_use]
25extern crate serde_derive;
26extern crate serde_json;
27extern crate term_size;
28#[cfg(windows)]
29extern crate winapi;
30
31use core::ruby_spy::RubySpy;
32
33use anyhow::Result;
34
35mod core;
36pub mod recorder;
37pub mod sampler;
38mod storage;
39pub mod ui;
40
41pub use crate::core::process::Pid;
42pub use crate::core::types::OutputFormat;
43pub use crate::core::types::StackFrame;
44pub use crate::core::types::StackTrace;
45
46/// Generate visualization (e.g. a flamegraph) from raw data that was previously recorded by rbspy
47pub fn report(
48    format: OutputFormat,
49    input: &mut dyn std::io::Read,
50    output: &mut dyn std::io::Write,
51) -> Result<()> {
52    let traces = storage::from_reader(input)?.traces;
53    let mut outputter = format.outputter(0.1);
54    for trace in traces {
55        outputter.record(&trace)?;
56    }
57    outputter.complete(output)?;
58    Ok(())
59}
60
61pub fn inspect(pid: Pid, force_version: Option<String>) -> Result<()> {
62    let ruby_spy = RubySpy::new(pid, force_version)?;
63    let vm = ruby_spy.inspect();
64    println!("Ruby version: {}", vm.ruby_version.semver_version);
65    println!("Ruby VM address: {:#x}", vm.ruby_vm_addr_location);
66    println!(
67        "Current thread address: {:#x}",
68        vm.current_thread_addr_location
69    );
70    println!(
71        "Global symbols address: {:#x}",
72        vm.global_symbols_addr_location.unwrap_or(0)
73    );
74
75    Ok(())
76}