Skip to content
Open
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
55 changes: 55 additions & 0 deletions crates/codspeed/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ fn main() {
println!("cargo:rerun-if-changed=instrument-hooks/includes/core.h");
println!("cargo:rerun-if-changed=build.rs");

collect_rustc_info();
collect_cargo_info();

let mut build = cc::Build::new();
build
.flag("-std=c11")
Expand Down Expand Up @@ -44,3 +47,55 @@ fn main() {
}
}
}

/// Collect rustc toolchain info at build time and expose as env vars.
/// These env var names must be kept in sync with `src/instrument_hooks/mod.rs`.
fn collect_rustc_info() {
let Ok(output) = std::process::Command::new("rustc")
.args(["--version", "--verbose"])
.output()
else {
return;
};
if !output.status.success() {
return;
}

let stdout = String::from_utf8_lossy(&output.stdout);
for line in stdout.lines() {
if let Some(rest) = line.strip_prefix("rustc ") {
println!("cargo:rustc-env=CODSPEED_RUSTC_VERSION={rest}");
} else if let Some((key, value)) = line.split_once(':') {
let key = key.trim();
let value = value.trim();
let env_key = match key {
"host" => Some("CODSPEED_RUSTC_HOST"),
"release" => Some("CODSPEED_RUSTC_RELEASE"),
"LLVM version" => Some("CODSPEED_RUSTC_LLVM_VERSION"),
_ => None,
};
if let Some(env_key) = env_key {
println!("cargo:rustc-env={env_key}={value}");
}
}
}
}

/// Collect cargo version at build time and expose as an env var.
/// This env var name must be kept in sync with `src/instrument_hooks/mod.rs`.
fn collect_cargo_info() {
let Ok(output) = std::process::Command::new("cargo")
.arg("--version")
.output()
else {
return;
};
if !output.status.success() {
return;
}

let stdout = String::from_utf8_lossy(&output.stdout);
if let Some(rest) = stdout.trim().strip_prefix("cargo ") {
println!("cargo:rustc-env=CODSPEED_CARGO_VERSION={rest}");
}
}
15 changes: 8 additions & 7 deletions crates/codspeed/src/codspeed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,20 @@ impl CodSpeed {
pub fn new() -> Self {
use crate::instrument_hooks::InstrumentHooks;
let instrumentation_status = {
// We completely bypass InstrumentHooks if we detect Valgrind via inline assembly
// Always initialize InstrumentHooks for environment collection,
// even when using Valgrind for the actual measurements.
let hooks_instance = InstrumentHooks::instance();

// We bypass InstrumentHooks if we detect Valgrind via inline assembly
// Until we can reliably get rid of the inline assembly without causing breaking
// changes in CPU simulation measurements by switching to InstrumentHooks only, we need
// to keep this separation.
if measurement::is_instrumented() {
InstrumentationStatus::Valgrind
} else if hooks_instance.is_instrumented() {
InstrumentationStatus::InstrumentHooks(hooks_instance)
} else {
let hooks_instance = InstrumentHooks::instance();
if hooks_instance.is_instrumented() {
InstrumentationStatus::InstrumentHooks(hooks_instance)
} else {
InstrumentationStatus::NotInstrumented
}
InstrumentationStatus::NotInstrumented
}
};

Expand Down
11 changes: 11 additions & 0 deletions crates/codspeed/src/instrument_hooks/bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,14 @@ pub type instrument_hooks_feature_t = ::std::os::raw::c_uint;
extern "C" {
pub fn instrument_hooks_set_feature(feature: instrument_hooks_feature_t, enabled: bool);
}
extern "C" {
pub fn instrument_hooks_set_environment(
arg1: *mut InstrumentHooks,
section_name: *const ::std::os::raw::c_char,
key: *const ::std::os::raw::c_char,
value: *const ::std::os::raw::c_char,
) -> u8;
}
extern "C" {
pub fn instrument_hooks_write_environment(arg1: *mut InstrumentHooks, pid: u32) -> u8;
}
76 changes: 76 additions & 0 deletions crates/codspeed/src/instrument_hooks/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,39 @@ mod linux_impl {
instance
.set_integration("codspeed-rust", env!("CARGO_PKG_VERSION"))
.expect("Failed to set integration");
instance.register_toolchain_environment();
instance
})
}

/// Registers Rust toolchain information (captured at build time) via the
/// environment API.
///
/// The env var names here must be kept in sync with `build.rs`.
fn register_toolchain_environment(&self) {
const SECTION: &str = "Rust";

if let Some(v) = option_env!("CODSPEED_RUSTC_VERSION") {
let _ = self.set_environment(SECTION, "rustc", v);
}
if let Some(v) = option_env!("CODSPEED_RUSTC_HOST") {
let _ = self.set_environment(SECTION, "host", v);
}
if let Some(v) = option_env!("CODSPEED_RUSTC_RELEASE") {
let _ = self.set_environment(SECTION, "release", v);
}
if let Some(v) = option_env!("CODSPEED_RUSTC_LLVM_VERSION") {
let _ = self.set_environment(SECTION, "LLVM version", v);
}
if let Some(v) = option_env!("CODSPEED_CARGO_VERSION") {
let _ = self.set_environment(SECTION, "cargo", v);
}

if let Err(e) = self.write_environment() {
eprintln!("Warning: failed to write environment info: {e}");
}
}

#[inline(always)]
pub fn is_instrumented(&self) -> bool {
unsafe { ffi::instrument_hooks_is_instrumented(self.0) }
Expand Down Expand Up @@ -131,6 +160,40 @@ mod linux_impl {
}
}

pub fn set_environment(
&self,
section_name: &str,
key: &str,
value: &str,
) -> Result<(), u8> {
let c_section = CString::new(section_name).map_err(|_| 1u8)?;
let c_key = CString::new(key).map_err(|_| 1u8)?;
let c_value = CString::new(value).map_err(|_| 1u8)?;
let result = unsafe {
ffi::instrument_hooks_set_environment(
self.0,
c_section.as_ptr(),
c_key.as_ptr(),
c_value.as_ptr(),
)
};
if result == 0 {
Ok(())
} else {
Err(result)
}
}

pub fn write_environment(&self) -> Result<(), u8> {
let pid = std::process::id();
let result = unsafe { ffi::instrument_hooks_write_environment(self.0, pid) };
if result == 0 {
Ok(())
} else {
Err(result)
}
}

pub fn disable_callgrind_markers() {
unsafe {
ffi::instrument_hooks_set_feature(
Expand Down Expand Up @@ -187,6 +250,19 @@ mod other_impl {
0
}

pub fn set_environment(
&self,
_section_name: &str,
_key: &str,
_value: &str,
) -> Result<(), u8> {
Ok(())
}

pub fn write_environment(&self) -> Result<(), u8> {
Ok(())
}

pub fn disable_callgrind_markers() {}
}
}
Expand Down
Loading