From 71ed34ca0f0a7c3ebd1d143d97df42f9f284cd02 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Wed, 15 May 2024 21:51:32 -0700 Subject: [PATCH 1/3] codegen: test frame pointer attr prefers CLI opt This test only makes sense if you send it back in time and run it with a now-old Rust commit, e.g. 50e0cc59ffcacda5b48f4edb95e5a5c353624fb0 However, if you do go back that far in time, you will see it pass. --- tests/codegen/frame-pointer-cli-control.rs | 35 ++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 tests/codegen/frame-pointer-cli-control.rs diff --git a/tests/codegen/frame-pointer-cli-control.rs b/tests/codegen/frame-pointer-cli-control.rs new file mode 100644 index 0000000000000..12282eea8f48b --- /dev/null +++ b/tests/codegen/frame-pointer-cli-control.rs @@ -0,0 +1,35 @@ +// compile-flags: --crate-type=rlib -Copt-level=0 +// revisions: force-on aarch64-apple aarch64-apple-off +// [force-on] compile-flags: -Cforce-frame-pointers=on +// [aarch64-apple] needs-llvm-components: aarch64 +// [aarch64-apple] compile-flags: --target=aarch64-apple-darwin +// [aarch64-apple-off] needs-llvm-components: aarch64 +// [aarch64-apple-off] compile-flags: --target=aarch64-apple-darwin -Cforce-frame-pointers=off +/* +Tests that the frame pointers can be controlled by the CLI. We find aarch64-apple-darwin useful +because of its icy-clear policy regarding frame pointers (software SHALL be compiled with them), +e.g. https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms says: + +* The frame pointer register (x29) must always address a valid frame record. Some functions — + such as leaf functions or tail calls — may opt not to create an entry in this list. + As a result, stack traces are always meaningful, even without debug information. +*/ +#![feature(no_core, lang_items)] +#![no_core] +#[lang = "sized"] +trait Sized {} +#[lang = "copy"] +trait Copy {} +impl Copy for u32 {} + +// CHECK: define i32 @peach{{.*}}[[PEACH_ATTRS:\#[0-9]+]] { +#[no_mangle] +pub fn peach(x: u32) -> u32 { + x +} + +// CHECK: attributes [[PEACH_ATTRS]] = { +// force-on-SAME: {{.*}}"frame-pointer"="all" +// aarch64-apple-SAME: {{.*}}"frame-pointer"="all" +// aarch64-apple-off-NOT: {{.*}}"frame-pointer"{{.*}} +// CHECK-SAME: } From 7fb5bc56c7fac792cf88cb7c54fc3b60fe8fd5ee Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Wed, 15 May 2024 21:57:01 -0700 Subject: [PATCH 2/3] codegen: modernize frame-pointer-cli-control.rs Update this time-traveler on the changes in compiletest and target specs that they missed over the pass ~3 years by being caught in a time rift. The aarch64-apple rev splits into itself and aarch64-apple-on, because rustc obtained support for non-leaf frame-pointers ever since 9b67cba implemented them and used them in aarch64-apple-darwin's spec. Note that the aarch64-apple-off revision fails, despite modernization. This is because 9b67cba also changed the behavior of rustc to defer to the spec over the command-line interface. --- tests/codegen/frame-pointer-cli-control.rs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/tests/codegen/frame-pointer-cli-control.rs b/tests/codegen/frame-pointer-cli-control.rs index 12282eea8f48b..7e7fe3ae497a3 100644 --- a/tests/codegen/frame-pointer-cli-control.rs +++ b/tests/codegen/frame-pointer-cli-control.rs @@ -1,10 +1,12 @@ -// compile-flags: --crate-type=rlib -Copt-level=0 -// revisions: force-on aarch64-apple aarch64-apple-off -// [force-on] compile-flags: -Cforce-frame-pointers=on -// [aarch64-apple] needs-llvm-components: aarch64 -// [aarch64-apple] compile-flags: --target=aarch64-apple-darwin -// [aarch64-apple-off] needs-llvm-components: aarch64 -// [aarch64-apple-off] compile-flags: --target=aarch64-apple-darwin -Cforce-frame-pointers=off +//@ compile-flags: --crate-type=rlib -Copt-level=0 +//@ revisions: force-on aarch64-apple aarch64-apple-on aarch64-apple-off +//@ [force-on] compile-flags: -Cforce-frame-pointers=on +//@ [aarch64-apple] needs-llvm-components: aarch64 +//@ [aarch64-apple] compile-flags: --target=aarch64-apple-darwin +//@ [aarch64-apple-on] needs-llvm-components: aarch64 +//@ [aarch64-apple-on] compile-flags: --target=aarch64-apple-darwin -Cforce-frame-pointers=on +//@ [aarch64-apple-off] needs-llvm-components: aarch64 +//@ [aarch64-apple-off] compile-flags: --target=aarch64-apple-darwin -Cforce-frame-pointers=off /* Tests that the frame pointers can be controlled by the CLI. We find aarch64-apple-darwin useful because of its icy-clear policy regarding frame pointers (software SHALL be compiled with them), @@ -30,6 +32,7 @@ pub fn peach(x: u32) -> u32 { // CHECK: attributes [[PEACH_ATTRS]] = { // force-on-SAME: {{.*}}"frame-pointer"="all" -// aarch64-apple-SAME: {{.*}}"frame-pointer"="all" +// aarch64-apple-SAME: {{.*}}"frame-pointer"="non-leaf" +// aarch64-apple-on-SAME: {{.*}}"frame-pointer"="all" // aarch64-apple-off-NOT: {{.*}}"frame-pointer"{{.*}} // CHECK-SAME: } From aaa10fefa608e65a24ea03b0a6febeb4334d00fb Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Wed, 15 May 2024 23:47:48 -0700 Subject: [PATCH 3/3] describe the force-frame-pointers dilemma in a TODO --- tests/codegen/frame-pointer-cli-control.rs | 39 +++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/tests/codegen/frame-pointer-cli-control.rs b/tests/codegen/frame-pointer-cli-control.rs index 7e7fe3ae497a3..f7ad41deb6ee6 100644 --- a/tests/codegen/frame-pointer-cli-control.rs +++ b/tests/codegen/frame-pointer-cli-control.rs @@ -10,12 +10,49 @@ /* Tests that the frame pointers can be controlled by the CLI. We find aarch64-apple-darwin useful because of its icy-clear policy regarding frame pointers (software SHALL be compiled with them), -e.g. https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms says: +e.g. says: * The frame pointer register (x29) must always address a valid frame record. Some functions — such as leaf functions or tail calls — may opt not to create an entry in this list. As a result, stack traces are always meaningful, even without debug information. */ +// Want the links to be clickable? Try: +// rustdoc +nightly ./tests/codegen/frame-pointer-cli-control.rs --out-dir=dilemma && xdg-open ./dilemma/frame_pointer_cli_control/index.htm +//! +//! TODO: T-compiler needs to make a decision about whether or not rustc should defer to the CLI +//! when given the -Cforce-frame-pointers flag, even when the target platform mandates it for ABI! +//! Considerations: +//! +//! - Many Rust fn, if externally visible, may be expected to follow ABI by tools or even asm code! +//! This can potentially make it unsound to generate ABI-incorrect (without frame pointers) code. +//! - Some platforms (e.g. illumos) seem to have unwinding completely break without frame-pointers: +//! - +//! - +//! - The code in more sophisticated backtrace and unwinding routines is notorious "dark magic" +//! that is poorly documented, understood by few, and prone to regressions for strange reasons. +//! Such unwinders in-theory allow using uwutables instead of frame pointers, but if they break? +//! For better or worse, these problems are often mended by forcing frame pointers: +//! - +//! - +//! - +//! - +//! - Those 32-bit x86 platforms that reputedly benefit the most from omitting frame pointers? +//! They also suffer the most from doing so, because of ancient unwinding/backtrace handling: +//! - +//! - +//! - +//! - +//! - Omitting frame-pointers may not meaningfully impact -Cpanic=abort binaries in function, but +//! some targets that default to panic=abort do force frame pointers to allow debugging to work, +//! even when they are notably pressed for space: +//! - +//! - There is, of course, the question of whether this compiler option was ever a good idea? +//! Some would say no: +//! - Despite all other remarks, it is true that the previous behavior was to defer to the CLI! +//! It may be considered a regression, but perhaps some platforms rely on that "regression". +//! Note the current behavior does uphold the doc's "without reading the source" contract: +//! - + #![feature(no_core, lang_items)] #![no_core] #[lang = "sized"]