|
| 1 | +# `instrument-function` |
| 2 | + |
| 3 | +Rust exposes several mechanisms to instrument functions which work with |
| 4 | +existing platform tooling: |
| 5 | + |
| 6 | +* xray |
| 7 | +* mcount (prof/gprof style profiling) |
| 8 | +* fentry (prof/gprof style profiling, though primarily used by the linux kernel). |
| 9 | + |
| 10 | +These options are mutually exclusive. Only one can be enabled when compiling a |
| 11 | +crate. These do not alter ABI, but may require implicit symbols to exist at |
| 12 | +link time. |
| 13 | + |
| 14 | +These are exposed via the `-Z instrument-function={mcount|fentry|xray|none}` |
| 15 | +option. |
| 16 | + |
| 17 | +A builtin attribute `instrument_fn` can be used to enable (as may be needed |
| 18 | +for xray), or disable instrumentation of the function. E.g.: |
| 19 | + |
| 20 | +```rust,no_run |
| 21 | +#![feature(instrument_fn)] |
| 22 | +#[instrument_fn = "off"] |
| 23 | +fn non_instrumented_function() { |
| 24 | +} |
| 25 | +``` |
| 26 | + |
| 27 | +# `-Z instrument-function=mcount` |
| 28 | + |
| 29 | +mcount instrumentation is a mechanism to insert a counting function call into |
| 30 | +the prologue of functions. This is traditionally used to perform profiling of |
| 31 | +a binary. In more recent years, mcount has been to implement features beyond |
| 32 | +profiling, such as logging, function patching, and tracing (see linux's |
| 33 | +[ftrace](https://docs.kernel.org/trace/ftrace.html)). This option is similiar |
| 34 | +to the `-pg` option provided by clang and gcc. This option also requires |
| 35 | +a frame-pointer to be enabled. |
| 36 | + |
| 37 | +This option only applies to the crate being compiled, and |
| 38 | + |
| 39 | +This feature is enabled via `-Zinstrument-function=mcount`, and an attribute |
| 40 | +is provided to prevent instrumentation of functions. |
| 41 | + |
| 42 | +On linux, an example might look like: |
| 43 | +```rust,no_run |
| 44 | +fn main() { |
| 45 | + println!("Hello world!"); |
| 46 | +} |
| 47 | +``` |
| 48 | + |
| 49 | +And compiling and running for gprof a fedora 44 x86-64 host: |
| 50 | + |
| 51 | +```shell |
| 52 | +$ rustc main.rs foo.rs -Zinstrument-function=mcount -C link-args=/usr/lib64/gcrt1.o -C link-self-contained |
| 53 | +$ ./main |
| 54 | +$ gprof main gmon.out |
| 55 | +``` |
| 56 | + |
| 57 | +gprof replaces parts of the C runtime implicitly linked into a binary. The above example is not |
| 58 | +suitable for most cases as rustc does not yet know how to substitude crt\*.o for gcrt\*.o when |
| 59 | +linking a binary. |
| 60 | + |
| 61 | +# `-Z instrument-function=fentry` |
| 62 | + |
| 63 | +On some targets, a more specialized form of mcount is available, named `fentry`. Unlike |
| 64 | +mcount, a frame-pointer is not required, and this is guaranteed to be called at function |
| 65 | +entry (hence the name). |
| 66 | + |
| 67 | +This support is restricted to fewer targets. Today, only x86 and s390x support this, and |
| 68 | +furthermore, only s390x supports advanced usage described below. |
| 69 | + |
| 70 | +## Advanced usage |
| 71 | + |
| 72 | +On supported targets, thee behavior of instrumentation can be further configured with the |
| 73 | +`-Zinstrument-mcount-opts` flag. It supports the following options: |
| 74 | + |
| 75 | +* `=record`: record the location of each call (or nop placeholder) into a section named |
| 76 | + `__mcount_loc`. This can be used to toggle the counting function at runtime. |
| 77 | + |
| 78 | +* `=no-call`: insert nop's which can be replaced by a call to a counting function. |
| 79 | + |
| 80 | +# `-Z instrument-function=xray` |
| 81 | + |
| 82 | +The tracking issue for the xray feature is: [#102921](https://github.com/rust-lang/rust/issues/102921). |
| 83 | + |
| 84 | +Enable generation of NOP sleds for XRay function tracing instrumentation. |
| 85 | +For more information on XRay, |
| 86 | +read [LLVM documentation](https://llvm.org/docs/XRay.html), |
| 87 | +and/or the [XRay whitepaper](http://research.google.com/pubs/pub45287.html). |
| 88 | + |
| 89 | +Set the `-Z instrument-function=xray` compiler flag in order to enable XRay instrumentation. |
| 90 | + |
| 91 | + - `-Z instrument-function=xray` – use the default settings |
| 92 | + - `-Z instrument-function=xray -Z instrument-xray-opts=skip-exit` – configure a custom setting |
| 93 | + - `-Z instrument-function=xray -Z instrument-xray-opts=ignore-loops,instruction-threshold=300` – |
| 94 | + multiple settings separated by commas |
| 95 | + |
| 96 | +Supported options: |
| 97 | + |
| 98 | + - `always` – force instrumentation of all functions |
| 99 | + - `never` – do no instrument any functions |
| 100 | + - `ignore-loops` – ignore presence of loops, |
| 101 | + instrument functions based only on instruction count |
| 102 | + - `instruction-threshold=10` – set a different instruction threshold for instrumentation |
| 103 | + - `skip-entry` – do no instrument function entry |
| 104 | + - `skip-exit` – do no instrument function exit |
| 105 | + |
| 106 | +The default settings are: |
| 107 | + |
| 108 | + - instrument both entry & exit from functions |
| 109 | + - instrument functions with at least 200 instructions, |
| 110 | + or containing a non-trivial loop |
| 111 | + |
| 112 | +Note that `-Z instrument-function=xray` only enables generation of NOP sleds |
| 113 | +which on their own don't do anything useful. |
| 114 | +In order to actually trace the functions, |
| 115 | +you will need to link a separate runtime library of your choice, |
| 116 | +such as Clang's [XRay Runtime Library](https://www.llvm.org/docs/XRay.html#xray-runtime-library). |
0 commit comments