Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,19 @@ impl Capture {
self.origin = origin;
}

/// Variables that turn on the wrappers, for a build started with `Command`.
#[cfg(target_os = "macos")]
pub fn child_environment(&self) -> impl Iterator<Item = (&OsStr, &OsStr)> {
self.child_environment.iter().map(|(name, value)| {
(
OsStr::from_bytes(name.as_bytes()),
OsStr::from_bytes(value.as_bytes()),
)
})
}

/// Apply already-prepared variables in the forked child without allocating.
#[cfg(target_os = "linux")]
pub unsafe fn configure_child(&self) {
for (name, value) in &self.child_environment {
// SAFETY: both strings are retained by `self`, NUL terminated, and
Expand Down
9 changes: 7 additions & 2 deletions src/macos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@
use self::event::Message;
use self::tracker::{Clock, TraceSink, Tracker};
use crate::blind_spots::BlindSpots;
use crate::compiler::Capture;
use crate::perfetto::Writer;
use std::ffi::{CString, OsString};
use std::io;
use std::path::Path;
use std::process::Command;
use std::time::{Duration, Instant};
use std::time::{Duration, Instant, SystemTime};

mod event;
mod kdebug;
Expand Down Expand Up @@ -71,6 +72,7 @@ pub fn record(
prepared: Prepared,
command: &[OsString],
writer: &mut Writer,
compilers: &mut Capture,
blind_spots: &mut BlindSpots,
file_events: bool,
) -> io::Result<u8> {
Expand All @@ -81,8 +83,11 @@ pub fn record(
} = prepared;
let program = command.first().expect("validated command");

// Compiler profiles carry wall-clock times; both origins are the same instant.
compilers.set_origin(SystemTime::now());
let mut build = Command::new(program)
.args(&command[1..])
.envs(compilers.child_environment())
.spawn()
.map_err(|error| {
io::Error::new(
Expand All @@ -99,7 +104,7 @@ pub fn record(
);
collector.seed_threads(threads);

let mut sink = TraceSink { writer };
let mut sink = TraceSink { writer, compilers };
let mut tracker = Tracker::new(
&mut sink,
blind_spots,
Expand Down
22 changes: 20 additions & 2 deletions src/macos/tracker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use super::event::{Event, Message};
use crate::blind_spots::BlindSpots;
use crate::compiler::Capture;
use crate::model::{FileOpen, Process, Rename, Segment};
use crate::perfetto::Writer;
use std::collections::{HashMap, HashSet};
Expand All @@ -26,11 +27,14 @@ pub trait Sink {
fn segment(&mut self, process: Process, segment: &Segment) -> io::Result<()>;
fn file_open(&mut self, pid: i32, open: &FileOpen) -> io::Result<()>;
fn rename(&mut self, pid: i32, rename: &Rename) -> io::Result<()>;
/// A process ended; import any compiler profile it left behind.
fn process_exited(&mut self, pid: i32, segment_start_ns: u64);
}

/// The trace being recorded.
/// The trace being recorded, with the compiler profiles that feed into it.
pub struct TraceSink<'a> {
pub writer: &'a mut Writer,
pub compilers: &'a mut Capture,
}

impl Sink for TraceSink<'_> {
Expand All @@ -46,6 +50,10 @@ impl Sink for TraceSink<'_> {
fn rename(&mut self, pid: i32, rename: &Rename) -> io::Result<()> {
self.writer.rename(pid, rename)
}
fn process_exited(&mut self, pid: i32, segment_start_ns: u64) {
self.compilers
.process_exited(pid, segment_start_ns, self.writer);
}
}

/// Converts `mach_absolute_time` ticks to nanoseconds since recording began.
Expand Down Expand Up @@ -338,7 +346,9 @@ impl<'a, S: Sink> Tracker<'a, S> {
);
state.segment.exit_code = Some(exit_code);
announce(self.sink, &mut self.announced, pid)?;
self.sink.segment(state.process, &state.segment)
self.sink.segment(state.process, &state.segment)?;
self.sink.process_exited(pid, state.segment.start_ns);
Ok(())
}
}

Expand Down Expand Up @@ -388,6 +398,9 @@ mod tests {
.push(format!("rename {pid} {} -> {}", rename.from, rename.to));
Ok(())
}
fn process_exited(&mut self, pid: i32, segment_start_ns: u64) {
self.0.push(format!("exited {pid} {segment_start_ns}"));
}
}

fn clock() -> Clock {
Expand Down Expand Up @@ -469,10 +482,13 @@ mod tests {
"start 12",
"open 12 30 /src/a.o flags=1101",
r#"segment 12 parent=10 build_parent=10 execed=true 15..40 "cc -c a.c" cwd=/src exit=Some(0)"#,
"exited 12 15",
"start 11",
r#"segment 11 parent=10 build_parent=10 execed=true 10..50 "sh -c true" cwd=/src exit=Some(2)"#,
"exited 11 10",
"start 10",
r#"segment 10 parent=0 build_parent=0 execed=true 0..60 "make -j2" cwd=/src exit=Some(0)"#,
"exited 10 0",
]
);
}
Expand All @@ -495,6 +511,8 @@ mod tests {
[
r#"segment 10 parent=0 build_parent=0 execed=true 0..5 "sh -c exec cc" cwd=/ exit=None"#,
r#"segment 10 parent=0 build_parent=0 execed=true 5..9 "cc" cwd=/ exit=Some(137)"#,
// Profiles are matched to the program that last ran in the pid.
"exited 10 5",
]
);
}
Expand Down
9 changes: 4 additions & 5 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ mod report;
mod args;
#[cfg_attr(not(any(target_os = "linux", target_os = "macos")), allow(dead_code))]
mod blind_spots;
#[cfg(target_os = "linux")]
#[cfg(any(target_os = "linux", target_os = "macos"))]
mod compiler;
mod handoff;
#[cfg(target_os = "linux")]
Expand All @@ -20,8 +20,7 @@ mod util;
// platform the viewer ships on.
#[cfg_attr(not(any(target_os = "linux", target_os = "macos")), allow(dead_code))]
mod model;
// Compiler traces are Linux-only for now.
#[cfg_attr(not(target_os = "linux"), allow(dead_code))]
#[cfg_attr(not(any(target_os = "linux", target_os = "macos")), allow(dead_code))]
mod perfetto;

use args::{Handoff, Wait};
Expand All @@ -31,7 +30,7 @@ use std::process::ExitCode;

fn main() -> ExitCode {
report::init();
#[cfg(target_os = "linux")]
#[cfg(any(target_os = "linux", target_os = "macos"))]
if let Some(code) = compiler::run_wrapper() {
return code;
}
Expand Down Expand Up @@ -114,7 +113,6 @@ fn record(
error!("could not write recording options: {error}");
return ExitCode::FAILURE;
}
#[cfg(target_os = "linux")]
let mut compilers = compiler::Capture::new(compiler_traces);
let mut blind_spots = blind_spots::BlindSpots::default();
#[cfg(target_os = "linux")]
Expand All @@ -130,6 +128,7 @@ fn record(
prepared,
&command,
&mut writer,
&mut compilers,
&mut blind_spots,
file_events,
);
Expand Down