Rollup merge of #133726 - joshtriplett:breakpoint, r=oli-obk

Add `core::arch::breakpoint` and test

Approved in [ACP 491](https://github.com/rust-lang/libs-team/issues/491).
This commit is contained in:
Matthias Krüger 2024-12-03 21:55:27 +01:00 committed by GitHub
commit e66e632479
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 66 additions and 13 deletions

View File

@ -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
@ -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(); } }
```

View File

@ -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

View File

@ -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.
// 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();
}

View File

@ -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!()
}

View File

@ -1,7 +1,5 @@
#![feature(core_intrinsics)]
fn main() {
unsafe {
core::intrinsics::breakpoint() //~ ERROR: trace/breakpoint trap
};
core::intrinsics::breakpoint(); //~ ERROR: trace/breakpoint trap
}

View File

@ -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

View File

@ -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();
}

View File

@ -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(); } }

View File

@ -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