Skip to content

Commit

Permalink
Rollup merge of #133726 - joshtriplett:breakpoint, r=oli-obk
Browse files Browse the repository at this point in the history
Add `core::arch::breakpoint` and test

Approved in [ACP 491](rust-lang/libs-team#491).
  • Loading branch information
matthiaskrgr authored Dec 3, 2024
2 parents 6e87eb5 + cea0582 commit e66e632
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 13 deletions.
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.
// 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
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

0 comments on commit e66e632

Please sign in to comment.