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

Add core::arch::breakpoint and test #133726

Merged
merged 2 commits into from
Dec 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions compiler/rustc_error_codes/src/error_codes/E0622.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ Erroneous code example:
#![allow(internal_features)]

extern "rust-intrinsic" {
pub static breakpoint: fn(); // error: intrinsic must be a function
pub static atomic_singlethreadfence_seqcst: fn();
// error: intrinsic must be a function
}

fn main() { unsafe { breakpoint(); } }
fn main() { unsafe { atomic_singlethreadfence_seqcst(); } }
```

An intrinsic is a function available for use in a given programming language
Expand All @@ -22,8 +23,8 @@ error, just declare a function. Example:
#![allow(internal_features)]

extern "rust-intrinsic" {
pub fn breakpoint(); // ok!
pub fn atomic_singlethreadfence_seqcst(); // ok!
}

fn main() { unsafe { breakpoint(); } }
fn main() { unsafe { atomic_singlethreadfence_seqcst(); } }
```
1 change: 1 addition & 0 deletions compiler/rustc_hir_analysis/src/check/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -
| sym::assert_inhabited
| sym::assert_zero_valid
| sym::assert_mem_uninitialized_valid
| sym::breakpoint
| sym::size_of
| sym::min_align_of
| sym::needs_drop
Expand Down
27 changes: 27 additions & 0 deletions library/core/src/arch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,30 @@ pub macro naked_asm("assembly template", $(operands,)* $(options($(option),*))?)
pub macro global_asm("assembly template", $(operands,)* $(options($(option),*))?) {
/* compiler built-in */
}

/// Compiles to a target-specific software breakpoint instruction or equivalent.
///
/// This will typically abort the program. It may result in a core dump, and/or the system logging
/// debug information. Additional target-specific capabilities may be possible depending on
/// debuggers or other tooling; in particular, a debugger may be able to resume execution.
///
/// If possible, this will produce an instruction sequence that allows a debugger to resume *after*
/// the breakpoint, rather than resuming *at* the breakpoint; however, the exact behavior is
/// target-specific and debugger-specific, and not guaranteed.
///
/// If the target platform does not have any kind of debug breakpoint instruction, this may compile
/// to a trapping instruction (e.g. an undefined instruction) instead, or to some other form of
/// target-specific abort that may or may not support convenient resumption.
///
/// The precise behavior and the precise instruction generated are not guaranteed, except that in
/// normal execution with no debug tooling involved this will not continue executing.
///
/// - On x86 targets, this produces an `int3` instruction.
/// - On aarch64 targets, this produces a `brk #0xf000` instruction.
Copy link
Member

Choose a reason for hiding this comment

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

Cranelift emits brk #0. Should this be changed on the Cranelift side?

Copy link
Member Author

Choose a reason for hiding this comment

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

@bjorn3 Yes, I think so. Some debuggers on aarch64 recognize brk #0xf000 as a hint to skip past that instruction when resuming.

Copy link
Member

Choose a reason for hiding this comment

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

// When stabilizing this, update the comment on `core::intrinsics::breakpoint`.
#[unstable(feature = "breakpoint", issue = "133724")]
#[inline(always)]
#[cfg(not(bootstrap))]
pub fn breakpoint() {
core::intrinsics::breakpoint();
}
12 changes: 12 additions & 0 deletions library/core/src/intrinsics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1381,6 +1381,18 @@ pub unsafe fn prefetch_write_instruction<T>(_data: *const T, _locality: i32) {
#[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden]
#[rustc_nounwind]
#[cfg(not(bootstrap))]
pub fn breakpoint() {
unreachable!()
}

/// Executes a breakpoint trap, for inspection by a debugger.
///
/// This intrinsic does not have a stable counterpart.
#[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden]
#[rustc_nounwind]
#[cfg(bootstrap)]
pub unsafe fn breakpoint() {
unreachable!()
}
Expand Down
4 changes: 1 addition & 3 deletions src/tools/miri/tests/fail/breakpoint.rs
oli-obk marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
#![feature(core_intrinsics)]

fn main() {
unsafe {
core::intrinsics::breakpoint() //~ ERROR: trace/breakpoint trap
};
core::intrinsics::breakpoint(); //~ ERROR: trace/breakpoint trap
}
4 changes: 2 additions & 2 deletions src/tools/miri/tests/fail/breakpoint.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error: abnormal termination: trace/breakpoint trap
--> tests/fail/breakpoint.rs:LL:CC
|
LL | core::intrinsics::breakpoint()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trace/breakpoint trap
LL | core::intrinsics::breakpoint();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trace/breakpoint trap
|
= note: BACKTRACE:
= note: inside `main` at tests/fail/breakpoint.rs:LL:CC
Expand Down
14 changes: 14 additions & 0 deletions tests/assembly/breakpoint.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//@ revisions: aarch64 x86_64
//@ assembly-output: emit-asm
//@[aarch64] only-aarch64
//@[x86_64] only-x86_64

#![feature(breakpoint)]
#![crate_type = "lib"]

// CHECK-LABEL: use_bp
// aarch64: brk #0xf000
// x86_64: int3
pub fn use_bp() {
core::arch::breakpoint();
}
4 changes: 2 additions & 2 deletions tests/ui/error-codes/E0622.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![feature(intrinsics)]
extern "rust-intrinsic" {
pub static breakpoint : unsafe extern "rust-intrinsic" fn();
pub static atomic_singlethreadfence_seqcst : unsafe extern "rust-intrinsic" fn();
//~^ ERROR intrinsic must be a function [E0622]
}
fn main() { unsafe { breakpoint(); } }
fn main() { unsafe { atomic_singlethreadfence_seqcst(); } }
4 changes: 2 additions & 2 deletions tests/ui/error-codes/E0622.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0622]: intrinsic must be a function
--> $DIR/E0622.rs:3:5
|
LL | pub static breakpoint : unsafe extern "rust-intrinsic" fn();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected a function
LL | pub static atomic_singlethreadfence_seqcst : unsafe extern "rust-intrinsic" fn();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected a function

error: aborting due to 1 previous error

Expand Down
Loading