Skip to content

Commit

Permalink
Add core::arch::breakpoint and test
Browse files Browse the repository at this point in the history
Approved in [ACP 491](rust-lang/libs-team#491).

Remove the `unsafe` on `core::intrinsics::breakpoint()`, since it's a
safe intrinsic to call and has no prerequisites.

(Thanks to @zachs18 for figuring out the `bootstrap`/`not(bootstrap)`
logic.)
  • Loading branch information
joshtriplett committed Dec 3, 2024
1 parent a522d78 commit 1be35f1
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 6 deletions.
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.
// 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();
}
16 changes: 14 additions & 2 deletions library/core/src/intrinsics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1375,12 +1375,24 @@ pub unsafe fn prefetch_write_instruction<T>(_data: *const T, _locality: i32) {
unreachable!()
}

/// Executes a breakpoint trap, for inspection by a debugger.
/// Compiles to a target-specific software breakpoint instruction or equivalent.
///
/// This intrinsic does not have a stable counterpart.
/// The (future) stabilized version of this intrinsic is [`core::arch::breakpoint`].
#[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden]
#[rustc_nounwind]
#[cfg(not(bootstrap))]
pub fn breakpoint() {
unreachable!()
}

/// Compiles to a target-specific software breakpoint instruction or equivalent.
///
/// The (future) stabilized version of this intrinsic is [`core::arch::breakpoint`].
#[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden]
#[rustc_nounwind]
#[cfg(bootstrap)]
pub unsafe fn breakpoint() {
unreachable!()
}
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

0 comments on commit 1be35f1

Please sign in to comment.