diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index b00e80a..e36aba6 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -16,7 +16,7 @@ jobs: - name: Install uses: actions-rs/toolchain@v1 with: - toolchain: nightly + toolchain: beta profile: minimal override: true - name: Build @@ -48,7 +48,7 @@ jobs: - name: Install uses: actions-rs/toolchain@v1 with: - toolchain: nightly + toolchain: beta target: ${{ matrix.target }} profile: minimal override: true diff --git a/Cargo.toml b/Cargo.toml index 1d085eb..49e11cb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,13 +1,13 @@ [project] name = "probe" -version = "0.2.1" +version = "0.3.0" authors = ["Josh Stone "] description = "Static instrumentation probes" documentation = "https://docs.rs/probe/" homepage = "https://github.com/cuviper/rust-libprobe" repository = "https://github.com/cuviper/rust-libprobe" license = "Apache-2.0 OR MIT" -edition = "2018" +edition = "2021" exclude = ["/.github/**"] [lib] diff --git a/README.md b/README.md index df3d50f..2cffcfc 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,38 @@ # libprobe: Static probes for Rust +[![probe crate](https://img.shields.io/crates/v/probe.svg)](https://crates.io/crates/probe) +![minimum rustc 1.59](https://img.shields.io/badge/rustc-1.59+-red.svg) +[![probe documentation](https://docs.rs/probe/badge.svg)](https://docs.rs/probe) +[![build status](https://github.com/cuviper/rust-libprobe/workflows/CI/badge.svg)](https://github.com/cuviper/rust-libprobe/actions) + With the `probe!` macro, programmers can place static instrumentation -points in their code to mark events of interest. These are compiled into -platform-specific implementations, e.g. SystemTap SDT on Linux. Probes are +points in their code to mark events of interest. These are compiled into +platform-specific implementations, e.g. SystemTap SDT on Linux. Probes are designed to have negligible overhead during normal operation, so they can be present in all builds, and only activated using those external tools. [Documentation](https://docs.rs/probe/) -## Building libprobe - -Simply run `rustc src/lib.rs` and copy the libprobe shared object to an -appropriate library path for your other rust projects. +## Using libprobe -If you're using cargo, just add this to your `Cargo.toml`: +[`probe!` is available on crates.io](https://crates.io/crates/probe). +The recommended way to use it is to add a line into your Cargo.toml such as: ```toml -[dependencies.probe] -git = "https://github.com/cuviper/rust-libprobe.git" +[dependencies] +probe = "0.3" ``` -Build status is available on Travis CI: -[![build status][ci-image]][ci-link] - -[ci-image]: https://api.travis-ci.org/cuviper/rust-libprobe.png -[ci-link]: https://travis-ci.org/cuviper/rust-libprobe +Then `use probe::probe;` in your code and insert macro calls wherever you want +to mark something, `probe!(provider, name, args...)`. The `provider` and `name` +are identifiers of your choice, and any additional arguments are runtime +expressions that will be cast `as isize` for the probe consumer to read. ## Rust integration I hope that this library can eventually be a standard part of the Rust distribution -- see the rust [pull request][libprobe-pr] and [original -enhancement issue][dtrace-issue]. It works fine as a standalone library, +enhancement issue][dtrace-issue]. It works fine as a standalone library, but if it were incorporated, then even Rust's own libraries could define probe points. diff --git a/examples/loop.rs b/examples/loop.rs index 46ca9cc..0e2f456 100644 --- a/examples/loop.rs +++ b/examples/loop.rs @@ -1,4 +1,3 @@ -#![feature(asm)] use probe::probe; fn main() { probe!(foo, begin); diff --git a/src/lib.rs b/src/lib.rs index 2639bdc..006e6c0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,18 +1,8 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - //! This crate provides static instrumentation macros. //! //! With the `probe!` macro, programmers can place static instrumentation -//! points in their code to mark events of interest. These are compiled into -//! platform-specific implementations, e.g. SystemTap SDT on Linux. Probes are +//! points in their code to mark events of interest. These are compiled into +//! platform-specific implementations, e.g. SystemTap SDT on Linux. Probes are //! designed to have negligible overhead during normal operation, so they can //! be present in all builds, and only activated using those external tools. //! @@ -23,7 +13,6 @@ //! intermediate total. //! //! ```rust -//! #![feature(asm)] //! use probe::probe; //! fn main() { //! probe!(foo, begin); @@ -89,14 +78,6 @@ //! $2 = 1035 //! ``` -#![crate_name = "probe"] -#![crate_type = "rlib"] -#![doc( - html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "http://www.rust-lang.org/favicon.ico", - html_root_url = "http://doc.rust-lang.org/nightly/" -)] -#![feature(asm)] #![no_std] mod platform; @@ -112,15 +93,14 @@ mod platform; /// /// * `name` - An identifier for this specific probe. /// -/// * `arg`... - Optional data to provide with the probe. Any expression which -/// can be cast `as i64` is allowed as an argument. The arguments might not +/// * `arg`... - Optional data to provide with the probe. Any expression which +/// can be cast `as isize` is allowed as an argument. The arguments might not /// be evaluated at all when a debugger is not attached to the probe, /// depending on the platform implementation, so don't rely on side effects. /// /// # Example /// /// ``` -/// #![feature(asm)] /// use probe::probe; /// fn main() { /// probe!(foo, main); diff --git a/src/platform/default.rs b/src/platform/default.rs index c7a7637..21aeed8 100644 --- a/src/platform/default.rs +++ b/src/platform/default.rs @@ -1,13 +1,3 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - #[doc(hidden)] #[macro_export] macro_rules! platform_probe( diff --git a/src/platform/mod.rs b/src/platform/mod.rs index 278fc38..501d2aa 100644 --- a/src/platform/mod.rs +++ b/src/platform/mod.rs @@ -1,13 +1,3 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - #[cfg(any(target_os = "linux", target_os = "android"))] mod systemtap; diff --git a/src/platform/systemtap.rs b/src/platform/systemtap.rs index c9c148b..e05ba6f 100644 --- a/src/platform/systemtap.rs +++ b/src/platform/systemtap.rs @@ -1,13 +1,3 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - //! SystemTap static probes //! //! This is a mechanism for developers to provide static annotations for @@ -22,10 +12,10 @@ //! //! # Links: //! -//! * https://sourceware.org/systemtap/man/stapprobes.3stap.html#lbAO (see `process.mark`) -//! * https://sourceware.org/systemtap/wiki/AddingUserSpaceProbingToApps -//! * https://sourceware.org/systemtap/wiki/UserSpaceProbeImplementation -//! * https://sourceware.org/gdb/onlinedocs/gdb/Static-Probe-Points.html +//! * (see `process.mark`) +//! * +//! * +//! * // // DEVELOPER NOTES @@ -63,33 +53,46 @@ // that log!() checks log_enabled!() first. // +#[cfg(target_pointer_width = "32")] +#[doc(hidden)] +#[macro_export] +macro_rules! platform_probe( + ($provider:ident, $name:ident,) + => ($crate::sdt_asm!(4, $provider, $name,)); + + ($provider:ident, $name:ident, $arg1:expr, $($arg:expr,)*) + => ($crate::sdt_asm!(4, $provider, $name, + "-4@{}", $arg1, $(" -4@{}", $arg,)*)); +); + +#[cfg(target_pointer_width = "64")] #[doc(hidden)] #[macro_export] macro_rules! platform_probe( ($provider:ident, $name:ident,) - => ($crate::sdt_asm!($provider, $name,)); + => ($crate::sdt_asm!(8, $provider, $name,)); ($provider:ident, $name:ident, $arg1:expr, $($arg:expr,)*) - => ($crate::sdt_asm!($provider, $name, - "-{size}@{}", $arg1, $(" -{size}@{}", $arg,)*)); + => ($crate::sdt_asm!(8, $provider, $name, + "-8@{}", $arg1, $(" -8@{}", $arg,)*)); ); #[cfg(any(target_arch = "x86_64", target_arch = "x86"))] #[doc(hidden)] #[macro_export] macro_rules! sdt_asm( - ($provider:ident, $name:ident, $($argstr:literal, $arg:expr,)*) + ($size:literal, $provider:ident, $name:ident, $($argstr:literal, $arg:expr,)*) => (unsafe { - $crate::_sdt_asm!(options(att_syntax), $provider, $name, $($argstr, $arg,)*); + $crate::_sdt_asm!($size, options(att_syntax), $provider, $name, $($argstr, $arg,)*); })); #[cfg(not(any(target_arch = "x86_64", target_arch = "x86")))] #[doc(hidden)] #[macro_export] macro_rules! sdt_asm( - ($provider:ident, $name:ident, $($argstr:literal, $arg:expr,)*) + ($size:literal, $provider:ident, $name:ident, $($argstr:literal, $arg:expr,)*) => (unsafe { - $crate::_sdt_asm!(options(), $provider, $name, $($argstr, $arg,)*); + $crate::_sdt_asm!($size, options(), $provider, $name, $($argstr, $arg,)*); })); // Since we can't #include , we have to reinvent it... @@ -97,17 +100,17 @@ macro_rules! sdt_asm( #[doc(hidden)] #[macro_export] macro_rules! _sdt_asm( - (options ($($opt:ident),*), $provider:ident, $name:ident, $($argstr:literal, $arg:expr,)*) => ( - asm!(concat!(r#" + ($size:literal, options ($($opt:ident),*), $provider:ident, $name:ident, $($argstr:literal, $arg:expr,)*) => ( + ::core::arch::asm!(concat!(r#" 990: nop .pushsection .note.stapsdt,"?","note" .balign 4 .4byte 992f-991f, 994f-993f, 3 991: .asciz "stapsdt" 992: .balign 4 -993: .{size}byte 990b - .{size}byte _.stapsdt.base - .{size}byte 0 // FIXME set semaphore address +993: ."#, $size, r#"byte 990b + ."#, $size, r#"byte _.stapsdt.base + ."#, $size, r#"byte 0 // FIXME set semaphore address .asciz ""#, stringify!($provider), r#"" .asciz ""#, stringify!($name), r#"" .asciz ""#, $($argstr,)* r#"" @@ -124,7 +127,6 @@ _.stapsdt.base: .space 1 "# ), $(in(reg) (($arg) as isize) ,)* - size = const core::mem::size_of::(), options(readonly, nostack, preserves_flags, $($opt),*), ) )); diff --git a/tests/readelf.rs b/tests/readelf.rs index c2daaef..104f555 100644 --- a/tests/readelf.rs +++ b/tests/readelf.rs @@ -1,5 +1,3 @@ -#![feature(asm)] - use probe::probe; use std::env; use std::process::Command;