mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-08 12:56:48 +00:00
Make cargo osdk profile
more fine-grained
This commit is contained in:
parent
c9e8666267
commit
faf2bcc3ef
@ -16,7 +16,14 @@ use crate::{
|
|||||||
util::{get_current_crates, get_target_directory},
|
util::{get_current_crates, get_target_directory},
|
||||||
};
|
};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::{collections::HashMap, fs::File, io::Write, path::PathBuf, process::Command};
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
fs::File,
|
||||||
|
io::{BufRead, Write},
|
||||||
|
path::PathBuf,
|
||||||
|
process::{Command, Stdio},
|
||||||
|
thread, time,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn execute_profile_command(_profile: &str, args: &ProfileArgs) {
|
pub fn execute_profile_command(_profile: &str, args: &ProfileArgs) {
|
||||||
if let Some(parse_input) = &args.parse {
|
if let Some(parse_input) = &args.parse {
|
||||||
@ -55,31 +62,60 @@ fn do_collect_stack_traces(args: &ProfileArgs) {
|
|||||||
let mut profile_buffer = ProfileBuffer::new();
|
let mut profile_buffer = ProfileBuffer::new();
|
||||||
|
|
||||||
println!("Profiling \"{}\" at \"{}\".", file_path.display(), remote);
|
println!("Profiling \"{}\" at \"{}\".", file_path.display(), remote);
|
||||||
|
// Use GDB to halt the remote, get stack traces, and resume
|
||||||
|
let mut gdb_process = {
|
||||||
|
let file_cmd = format!("file {}", file_path.display());
|
||||||
|
let target_cmd = format!("target remote {}", remote);
|
||||||
|
let backtrace_cmd_seq = vec![
|
||||||
|
"-ex",
|
||||||
|
"thread apply all bt -frame-arguments presence -frame-info short-location",
|
||||||
|
"-ex",
|
||||||
|
"echo bt done\n",
|
||||||
|
"-ex",
|
||||||
|
"continue",
|
||||||
|
];
|
||||||
|
|
||||||
|
let mut gdb_args = vec![
|
||||||
|
"-batch",
|
||||||
|
"-ex",
|
||||||
|
"set pagination 0",
|
||||||
|
"-ex",
|
||||||
|
&file_cmd,
|
||||||
|
"-ex",
|
||||||
|
&target_cmd,
|
||||||
|
];
|
||||||
|
gdb_args.append(&mut vec![backtrace_cmd_seq; *samples].concat());
|
||||||
|
|
||||||
|
Command::new("gdb")
|
||||||
|
.args(gdb_args)
|
||||||
|
.stdout(Stdio::piped())
|
||||||
|
.spawn()
|
||||||
|
.expect("Failed to execute gdb")
|
||||||
|
};
|
||||||
|
|
||||||
|
let gdb_stdout = gdb_process.stdout.take().unwrap();
|
||||||
|
let mut gdb_stdout_reader = std::io::BufReader::new(gdb_stdout);
|
||||||
|
let mut gdb_stdout_buf = String::new();
|
||||||
|
let mut gdb_output = String::new();
|
||||||
use indicatif::{ProgressIterator, ProgressStyle};
|
use indicatif::{ProgressIterator, ProgressStyle};
|
||||||
let style = ProgressStyle::default_bar().progress_chars("#>-");
|
let style = ProgressStyle::default_bar().progress_chars("#>-");
|
||||||
for _ in (0..*samples).progress_with_style(style) {
|
for _ in (0..*samples).progress_with_style(style) {
|
||||||
// Use GDB to halt the remote, get stack traces, and resume
|
loop {
|
||||||
let output = Command::new("gdb")
|
let _ = gdb_stdout_reader.read_line(&mut gdb_stdout_buf);
|
||||||
.args([
|
gdb_output.push_str(&gdb_stdout_buf);
|
||||||
"-batch",
|
if gdb_stdout_buf == "bt done\n" {
|
||||||
"-ex",
|
break;
|
||||||
"set pagination 0",
|
}
|
||||||
"-ex",
|
gdb_stdout_buf.clear();
|
||||||
&format!("file {}", file_path.display()),
|
}
|
||||||
"-ex",
|
let _ = Command::new("kill")
|
||||||
&format!("target remote {}", remote),
|
.args(["-INT", &format!("{}", gdb_process.id())])
|
||||||
"-ex",
|
.spawn();
|
||||||
"thread apply all bt -frame-arguments presence -frame-info short-location",
|
for line in gdb_output.lines() {
|
||||||
])
|
|
||||||
.output()
|
|
||||||
.expect("Failed to execute gdb");
|
|
||||||
|
|
||||||
for line in String::from_utf8_lossy(&output.stdout).lines() {
|
|
||||||
profile_buffer.append_raw_line(line);
|
profile_buffer.append_raw_line(line);
|
||||||
}
|
}
|
||||||
|
gdb_output.clear();
|
||||||
// Sleep between samples
|
thread::sleep(time::Duration::from_secs_f64(*interval));
|
||||||
std::thread::sleep(std::time::Duration::from_secs_f64(*interval));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let out_args = &args.out_args;
|
let out_args = &args.out_args;
|
||||||
@ -196,7 +232,7 @@ impl ProfileBuffer {
|
|||||||
// Otherwise it may initiate a new capture or a new CPU stack trace
|
// Otherwise it may initiate a new capture or a new CPU stack trace
|
||||||
|
|
||||||
// Check if this is a new CPU trace (starts with `Thread` and contains `CPU#N`)
|
// Check if this is a new CPU trace (starts with `Thread` and contains `CPU#N`)
|
||||||
if line.starts_with("Thread") {
|
if line.ends_with("[running])):") {
|
||||||
let cpu_id_idx = line.find("CPU#").unwrap();
|
let cpu_id_idx = line.find("CPU#").unwrap();
|
||||||
let cpu_id = line[cpu_id_idx + 4..]
|
let cpu_id = line[cpu_id_idx + 4..]
|
||||||
.split_whitespace()
|
.split_whitespace()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user