Skip to content

RFC: Add compiler support for instrumenting functions#3917

Open
pmur wants to merge 6 commits into
rust-lang:masterfrom
pmur:murp/instrumented-functions
Open

RFC: Add compiler support for instrumenting functions#3917
pmur wants to merge 6 commits into
rust-lang:masterfrom
pmur:murp/instrumented-functions

Conversation

@pmur

@pmur pmur commented Feb 10, 2026

Copy link
Copy Markdown

This RFC proposes to add support for instrumenting function calls using mcount fentry or xray, and adding a new builtin attribute to toggle instrumentation.

Today, mcount and xray enjoy experimental support, but I was unable to find any RFC proposing their inclusion.

Rendered

Comment thread text/0000-instrumented-functions.md Outdated
* [XRay](https://llvm.org/docs/XRay.html), an LLVM project to instrument both entry and exit of functions,
with dynamic enablement.

These features are all very similar, are effectively mutually exclusive (e.g., mcount and fentry).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
These features are all very similar, are effectively mutually exclusive (e.g., mcount and fentry).
These features are all very similar, and are effectively mutually exclusive (e.g., mcount and fentry).


### Language additions

A single builtin attribute, `instrument_fn`, will be added. It will be applied to functions and methods

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe there should be #[instrument_fn = "off"] or similar to opt out of all function instrumentation, not just entry/exit (you mentioned loop instrumentation earlier), that would be useful when implementing the instrumentation function to avoid recursively calling itself.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For usability, that seems nice for most common cases. I'll add it.

As for ignore-loops, it is an xray option to modify its heuristics for deciding to whether to instrument the function. I wonder if there is a case where you want to instrument more than *logues, but less than every basic block.

@ehuss ehuss added T-lang Relevant to the language team, which will review and decide on the RFC. T-compiler Relevant to the compiler team, which will review and decide on the RFC. labels Feb 10, 2026
Comment on lines +157 to +158
## Prior art
[prior-art]: #prior-art

@Darksonn Darksonn Feb 11, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does this related to RFC patchable-function-entry by @maurer ?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For linux ftrace, both provide similar features. Though, x86-64 seems to support both, and some distros use both. I am curious why.

For using existing instrumentation frameworks like gprof or xray, there are more expectations beyond inserting and tracking nops at entry.

pmur added 3 commits February 11, 2026 16:51
* Add `#[instrument_fn = "off"]` form.

* s/linux/Linux/ when used as a proper noun.

* Add prior art paragraph about patachable-function-entries rfc.

* Clarify `ignore-loops` xray option.
With the current instrumentation frameworks, I don't think there
is benefit to fine grain controls. I have simplified the attribute
to "on" and "off".

XRay has some creative options, but fine grain control of entry
and exit instrumentation insertion probably isn't useful.
@pmur

pmur commented Mar 11, 2026

Copy link
Copy Markdown
Author

I've also created a draft PR for implementation, rust-lang/rust#153742.

@nikic

nikic commented Mar 28, 2026

Copy link
Copy Markdown

I think the RFC needs some more clarity on why we want/need to support all of these instrumentation options. In particular, for mcount I'm not sure we should be moving towards stabilization, rather than moving towards removal.

The RFC mentions two potential use cases, one being gprof (which, I think, has been pretty much completely superseded by other profiling tools nowadays) and the other kernel ftrace. Ftrace also supports using patchable function entries instead, and as far as I know, that is the generally preferred mechanism. I think some legacy architectures (most of which rustc doesn't even support) use mcount because patchable function entry is not implemented for them -- but that's probably better addressed by implementing it, if anyone actually cares.

One thing I'm particularly concerned about is exposing something that has very fragmented platform support. E.g. LLVM currently only supports -mrecord-mcount and -mnop-mcount (here as -Z instrument-mcount-opts=record and -Z instrument-mcount-opts=no-call) on the s390x architecture, and their functionality is essentially a subset of what -Z patchable-function-entry provides (on more architectures).

If the kernel has sound technical reasons for why it uses it uses -pg -mrecord-mcount -mnop-mcount on one platform and -fpatchable-function-entry on another, we should find out what those are and document them. If it doesn't (that is, the reason is historical) then I think we should encourage the kernel to consolidate their instrumentation mechanism, rather than replicating this patchwork approach in Rust.

@Darksonn

Darksonn commented Mar 28, 2026

Copy link
Copy Markdown
Member

Linux Kernel still uses mcount for ftrace on x86_64.

@nikic

nikic commented Mar 28, 2026

Copy link
Copy Markdown

Linux Kernel still uses mcount for ftrace on x86_64.

Does it use mcount or fentry? I thought it was the latter.

@Darksonn

Copy link
Copy Markdown
Member

Hmm, as I read the makefile, it passes -mrecord-mcount and -mfentry. But it doesn't use patchable function entry, like it does on arm64.

@pmur

pmur commented Mar 31, 2026

Copy link
Copy Markdown
Author

Does it use mcount or fentry? I thought it was the latter.

Both, the functionality intertwined. I believe the usage looks something like -pg -fentry -mnop-mcount -mrecord-mcount for dynamic ftrace on x86_64.

I also learned that -pg on the x86_64*windows*gnu gcc toolchains also uses fentry. glibc and cywin implement both counting functions on x86.

I think there is still utility for these counting functions where there is no operating system, or a robust sampling profiler is not available.

@pmur

pmur commented May 13, 2026

Copy link
Copy Markdown
Author

I sent a mail to lkml seeking answers and advice to some of the open questions. fentry seems like it will only ever be suitable for architectures like s390 and x86. Though, I haven't received any feedback from maintainers.

I wonder if adding an annotation to allow overriding the default section where patchable-function-entries stores records would be sufficient to replace the usage of fentry.

Simplify command-line usage by passing configuration options alongside
the framework selection. The extra command line options felt excessive.

Likewise, clarify the configurable options for mcount. Today, llvm
supports none. Likewise, the primary user of these, linux, uses fentry
and patchable-function-entries. They could be added in the future, but
are unlikely to be used.
The linux kernel could, but doesn't actively use the -mnop-mcount and
-mrecord-mcount options by default. It uses its build tooling instead.

Also, try to clarify the linux kernel's usage of patchable-function-entries
and fentry on x86. It's complicated; fentry probably isn't going away
anytime soon.
jhpratt added a commit to jhpratt/rust that referenced this pull request Jun 17, 2026
…r=oli-obk,mejrs

Add instrument_fn attribute

This attribute enables or disables function instrumentation when using `-Zinstrument-xray` or `-Zinstrument-mcount`.

It supports the following usage:

`#[instrument_fn = "on|off"]`

For XRay, "on" is equivalent to always instrument, and "off" is equivalent to never instrumenting.

For mcount, "on" has no effect. "off" disables instrumentation of the function.

This is tracked by rust-lang#157081, and related to the pending rfc rust-lang/rfcs#3917, and earlier as part mcp rust-lang/compiler-team#561
@nikomatsakis

nikomatsakis commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Speaking personally (not on behalf of a team), I support the goal that Rust can do integrate with anything a C compiler can integrate with and that makes me inclined in favor of this RFC, particularly since I think the RfL folks are interested in it. I don't know enough about this area to judge if this is the right set of things. Having a specific list of integrations feels a bit special-case to me but maybe it makes sense.

Longer term, I want the Rust compiler to be more extensible, so that this kind of use-cases could be supported as a library, but that's neither here nor there (I wouldn't block on it). 😁

@nikomatsakis

Copy link
Copy Markdown
Contributor

One other note:

The RFC should not be talking about -Z. -Z represents inherently unstable surface area, so you would never need it in an RFC. I would expect the RFC to proposal stable compiler options.

(We often start with a -Z flag and then migrate to a stable flag later, but I think that's not really the ideal pattern anyway, this is what -Zunstable-options is for.)

@joshtriplett

Copy link
Copy Markdown
Member

This is certainly well-motivated, and many users want this, including Rust-for-Linux. @rust-lang/lang felt like most of this is more a compiler matter than a lang one, and the lang surface area is somewhat minimally exposing that (via an attribute on functions).

We may not necessarily want to expose, in a lang attribute, the ability to choose on a function-by-function basis which instrumentation you're using. We had the general feeling, when discussing this, that we'd expect the compiler flags to choose a supported instrumentation framework, and then the lang attribute should just be toggling such instrumentation. For instance, "this function is not instrumented", so that it doesn't create recursion because it's called from the instrumentation internals, and possibly also a mechanism for "this function is instrumented".

@joshtriplett

Copy link
Copy Markdown
Member

Speaking for myself: I also think we should ask the question of whether we want to support all of these different instrumentation mechanisms, or if we want to support a subset of them. Ultimately, I think that's a question of what the compiler wants to support, and the lang surface area shouldn't expose which one is in use. But I'd be interested to know if the prospective users of which (e.g. Rust-for-Linux) need support for all of them or just a subset.

@pmur

pmur commented Jul 8, 2026

Copy link
Copy Markdown
Author

I think RfL is only interested in the narrow slice required to support fentry/ftrace for x86, and the related ability to disable it per function. Most (all?) the other architectures are exclusively using patchable-function-entries; they don't have to contend with the security mitigations which complicate x86.

All the interesting bits of this RFC are implemented as experimental features now. fentry support is bolted onto -Zinstrument-mcount. I think the only question this RFC asks is whether these frameworks should be wrapped into a single option.

Now, I am not sure if there is much value in consolidating the options. I think stabilizing mcount and the language attribute are the only useful parts. Is there still interest in xray instrumentation?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

T-compiler Relevant to the compiler team, which will review and decide on the RFC. T-lang Relevant to the language team, which will review and decide on the RFC.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants