Thanks so much for the response! clang and rustc (by design on Rust' part, to be clear!) are sufficiently similar that it was pretty easy to translate between C++ and Rust!
Your tips/suggestions almost worked for me, except that the binary would be sigkilled'd immediately after launch. I did some rubber-duck debugging using Claude, and it—rather impressively!—pointed out in https://claude.ai/share/5a4ca3ca-9e98-4e2a-b9ae-71b49c6983cf that the entitlement I needed to use was com.apple.security.get-task-allow, not com.apple.security-get-task-allow. Instruments' diagnostic contained a typo! Once I fixed this typo, I was able to use the "Processor Trace" instrument via xctrace. Of course, since this is beta software, which I hit a few bugs, which I'll cover at the end of this post.
Apple silicon code must be signed, so the linker automatically applies an ad-hoc signature. You can see this if you dump the hello tool before re-signing it: [dump redacted]
If you’re going to re-sign the binary anyway, you can disable linker signing with the -no_adhoc_codesign linker option.
I think the Rust compiler sets the adhoc signature somewhere by default, so while I agree it's kinda wasteful to replace it later, it's also not the worst.
but it’s not appropriate for a product that you want to ship to a wide range of users
Yeah, I figured as such. I'm only really using these adhoc binaries for as part of my local development workflow.
The Bugs!
Anyways! I promised a few bug reports, here they are!
Typo in Diagnostics
Instruments and xctrace have a typo in their disagnostics entitlement: they both suggest com.apple.security-get-task-allow instead of com.apple.security.get-task-allow. I spent my morning scratching my head over this. See below for the typo:
❯ xctrace record --template 'Processor Trace' --target-stdout - --launch -- target/dev-rel/deps/hir_ty-f1dbf1b1d36575fe --exact tests::incremental::add_struct_invalidates_trait_solve
Starting recording with the Processor Trace template. Launching process: hir_ty-f1dbf1b1d36575fe.
Ctrl-C to stop the recording
Run issues were detected (trace is still ready to be viewed):
* [Error] Processor Trace cannot profile this process without proper permissions.
* [Error] Recovery Suggestion: Either:
1. Add the 'com.apple.security-get-task-allow' entitlement to your binary entitlements file, or
2. Make sure the build setting CODE_SIGN_INJECT_BASE_ENTITLEMENTS = YES is enabled when building with Xcode.
Recording failed with errors. Saving output file...
Output file saved as: Launch_hir_ty-f1dbf1b1d36575fe_2025-07-02_13.39.40_EBCB3760.trace
OOMs in Instruments
I had to use xctrace record --template 'Processor Trace' --target-stdout - --launch -- hir_ty-f1dbf1b1d36575fe --exact tests::incremental::add_struct_invalidates_trait_solve from my shell instead of launching from Instruments directly, as Instruments ended up using something like 130 GB of RAM, forcing me to restart my Mac. I have only have a paltry 48GB!
An Entitlement for Profiling using Hardware Profiling Features Feels Strange
I would personally expect that a linker-signed, adhoc binary would imply com.apple.security.get-task-allow. Some additional, assorted thoughts:
rustc tends to use the system's C compilers to indirectly drive the linker, which means that if there's some feature that the linker should be doing automatically on said platform, the Rust compiler does it. Given that the Rust compiler produces adhoc-signed binaries by default and I can debug those binaries using lldb without any additional entitlements, I'd expect the same of hardware-supported CPU execution tracing (modulo restarting my Mac), especially if the CPU execution tracing in M4 processors is anything similar to similar to Intel's Processor Trace: https://lldb.llvm.org/use/intel_pt.html.
A friend pointed out that your phrasing of "That is, the signature applied by the linker" should have clued me into the fact that there's some linker magic happening with ld_prime. Cards on the table, I think there should be a little more magic happening :D.
The new profiling functionality is downright magical. It just works with non-Swift/C/Objective-C languages and I feel like it's a shame that end-users need to become deeply familiar with codesigning to use this incredible set of tooling. Heck, I bought the Mac I'm writing this post on two days ago in order to use this feature!
Anyways, thanks so much for your help and let me know if I can provide any additional detail!