From cea444203d7766e090dc597575667dcd7fc8d40a Mon Sep 17 00:00:00 2001 From: yoinspiration Date: Sat, 20 Dec 2025 13:04:32 +0800 Subject: [PATCH 1/2] fix: skip breakpoint/other exceptions on aarch64 to match Linux behavior - Handle ExceptionKind::Breakpoint by skipping instruction on aarch64 - Handle ExceptionKind::Other by skipping instruction on aarch64 - Fixes ffmpeg --help crash with 'Trace/breakpoint trap' on aarch64 - Matches Linux behavior where breakpoint instructions are ignored when not debugged --- api/src/task.rs | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/api/src/task.rs b/api/src/task.rs index fb680a39..a28f9211 100644 --- a/api/src/task.rs +++ b/api/src/task.rs @@ -63,7 +63,8 @@ pub fn new_user_task( #[allow(unused_labels)] ReturnReason::Exception(exc_info) => 'exc: { // TODO: detailed handling - let signo = match exc_info.kind() { + let exc_kind = exc_info.kind(); + let signo = match exc_kind { ExceptionKind::Misaligned => { #[cfg(target_arch = "loongarch64")] if unsafe { uctx.emulate_unaligned() }.is_ok() { @@ -71,9 +72,40 @@ pub fn new_user_task( } Signo::SIGBUS } - ExceptionKind::Breakpoint => Signo::SIGTRAP, + ExceptionKind::Breakpoint => { + // On aarch64, skip breakpoint instructions (brk) to match Linux behavior. + // When a process is not being debugged, breakpoint instructions are ignored. + #[cfg(target_arch = "aarch64")] + { + // brk instruction is 4 bytes on aarch64 + let current_pc = uctx.ip(); + let next_pc = current_pc + 4; + debug!("Skipping breakpoint instruction at {:#x}, setting PC to {:#x}", current_pc, next_pc); + uctx.set_ip(next_pc); + break 'exc; + } + #[cfg(not(target_arch = "aarch64"))] + Signo::SIGTRAP + } ExceptionKind::IllegalInstruction => Signo::SIGILL, - _ => Signo::SIGTRAP, + _ => { + // On aarch64, some breakpoint-related exceptions (like brk) may be reported + // as "Other" instead of "Breakpoint". Try to skip the instruction to match + // Linux behavior where breakpoint instructions are ignored when not debugged. + #[cfg(target_arch = "aarch64")] + { + let current_pc = uctx.ip(); + let next_pc = current_pc + 4; + debug!("Attempting to skip exception type {:?} at PC {:#x}, setting PC to {:#x}", exc_kind, current_pc, next_pc); + uctx.set_ip(next_pc); + break 'exc; + } + #[cfg(not(target_arch = "aarch64"))] + { + warn!("Unhandled exception type: {:?} at PC {:#x}", exc_kind, uctx.ip()); + Signo::SIGTRAP + } + } }; raise_signal_fatal(SignalInfo::new_kernel(signo)) .expect("Failed to send SIGTRAP"); From bf9e523103a01f446abb9b29b015b72f5967897a Mon Sep 17 00:00:00 2001 From: yoinspiration Date: Sat, 20 Dec 2025 13:18:05 +0800 Subject: [PATCH 2/2] style: format code with cargo fmt --- api/src/task.rs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/api/src/task.rs b/api/src/task.rs index a28f9211..048054c2 100644 --- a/api/src/task.rs +++ b/api/src/task.rs @@ -80,7 +80,11 @@ pub fn new_user_task( // brk instruction is 4 bytes on aarch64 let current_pc = uctx.ip(); let next_pc = current_pc + 4; - debug!("Skipping breakpoint instruction at {:#x}, setting PC to {:#x}", current_pc, next_pc); + debug!( + "Skipping breakpoint instruction at {:#x}, setting PC to \ + {:#x}", + current_pc, next_pc + ); uctx.set_ip(next_pc); break 'exc; } @@ -96,13 +100,21 @@ pub fn new_user_task( { let current_pc = uctx.ip(); let next_pc = current_pc + 4; - debug!("Attempting to skip exception type {:?} at PC {:#x}, setting PC to {:#x}", exc_kind, current_pc, next_pc); + debug!( + "Attempting to skip exception type {:?} at PC {:#x}, \ + setting PC to {:#x}", + exc_kind, current_pc, next_pc + ); uctx.set_ip(next_pc); break 'exc; } #[cfg(not(target_arch = "aarch64"))] { - warn!("Unhandled exception type: {:?} at PC {:#x}", exc_kind, uctx.ip()); + warn!( + "Unhandled exception type: {:?} at PC {:#x}", + exc_kind, + uctx.ip() + ); Signo::SIGTRAP } }