Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support conditional SystemTap probes using semaphores #17

Merged
merged 9 commits into from
Jan 3, 2023

Conversation

nbaksalyar
Copy link
Contributor

@nbaksalyar nbaksalyar commented Apr 25, 2022

This is a proof-of-concept implementation of #16 (more of an RFC for now rather than a complete thing).

Unfortunately, this implementation requires use of procedural macros because there's no other easy way to define static variables in a macro (global vars defined in inline asm didn't work).

I also couldn't find any easy way to implement probe_enabled!. Most likely, it will require the use of something like std::sync::Once/lazy_static to maintain a "registry" of probes. Even then, SystemTap expects a link-time address of a semaphore variable (unless we want to use dynamically defined probes?). I think having a separate macro like probe_opt! which will lazily evaluate its arguments is a fine compromise.

  • Use a separate probe_opt! macro for probes with semaphores.
  • Document the semaphores implementation.
  • Document procedural macros and naming conventions.
  • Add more examples using semaphores.
  • Add tests.
  • Add usage examples in readme.

@cuviper
Copy link
Owner

cuviper commented Apr 27, 2022

If we set aside probe_enabled!, I think #![feature(asm_sym)] (rust-lang/rust#93333) will make this much easier. We can let macro hygiene deal with creating a unique mangled name for the semaphore, and just pass that to the assembly.

--- a/src/platform/systemtap.rs
+++ b/src/platform/systemtap.rs
@@ -101,6 +101,8 @@ macro_rules! sdt_asm(
 #[macro_export]
 macro_rules! _sdt_asm(
     ($size:literal, options ($($opt:ident),*), $provider:ident, $name:ident, $($argstr:literal, $arg:expr,)*) => (
+        static mut SEMAPHORE: u16 = 0;
+        if SEMAPHORE > 0 {
         ::core::arch::asm!(concat!(r#"
 990:    nop
         .pushsection .note.stapsdt,"?","note"
@@ -110,7 +112,7 @@ macro_rules! _sdt_asm(
 992:    .balign 4
 993:    ."#, $size, r#"byte 990b
         ."#, $size, r#"byte _.stapsdt.base
-        ."#, $size, r#"byte 0 // FIXME set semaphore address
+        ."#, $size, r#"byte {}
         .asciz ""#, stringify!($provider), r#""
         .asciz ""#, stringify!($name), r#""
         .asciz ""#, $($argstr,)* r#""
@@ -126,7 +128,9 @@ _.stapsdt.base: .space 1
 .endif
 "#
             ),
+            sym SEMAPHORE,
             $(in(reg) (($arg) as isize) ,)*
             options(readonly, nostack, preserves_flags, $($opt),*),
         )
+        }
     ));

This works for me for lazy evaluation, even in a release build. I suppose we could add a #[link_section = ".probes"] on that static, but I honestly don't remember why SystemTap does that.

What do you think?

@nbaksalyar
Copy link
Contributor Author

feature(asm_sym)

I wasn’t aware of this, looks awesome! Definitely makes it a lot simpler. But it will require to wait for the next stable release or to use the nightly toolchain though, right?

I think the .probes section is optional (but I’ll double-check that).

@cuviper
Copy link
Owner

cuviper commented Apr 27, 2022

But it will require to wait for the next stable release or to use the nightly toolchain though, right?

It would be in the next full release cycle after they actually stabilize that feature, yes, but it looks like that might be close. e.g. that would be headed for Rust 1.62 if it stabilized today. In the meantime, it needs nightly with the opt-in feature attribute, but I'd rather wait for stabilization.

@nbaksalyar
Copy link
Contributor Author

I'd rather wait for stabilization.

Cool, I’m going to fix this PR and add docs/examples in the meantime then.

@cuviper
Copy link
Owner

cuviper commented Dec 14, 2022

FYI, asm_sym is stabilizing in Rust 1.66 tomorrow, December 15th.

@nbaksalyar nbaksalyar marked this pull request as ready for review December 16, 2022 13:44
This prevents a warning that was seen in the examples on wasm.
The semaphore value is incremented by each attached tool, so we should
check if it's non-zero, not just exactly 1.
This is mainly so they're not placed in read-only memory. Most debugging
tools can poke RO memory anyway, but SystemTap puts its semaphores in
the RW `.probes` section.
@cuviper cuviper merged commit 2d1567c into cuviper:master Jan 3, 2023
@cuviper
Copy link
Owner

cuviper commented Jan 3, 2023

Thanks! I've published 0.4.0.

@nbaksalyar nbaksalyar deleted the sdt-semaphores branch January 3, 2023 21:19
@nbaksalyar
Copy link
Contributor Author

Thanks! I've published 0.4.0.

Excellent, thank you so much for reviewing and the improvements :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants