mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-30 05:51:58 +00:00
Don't trap into the debugger on panics under Linux
This breaks `rr`, see https://github.com/rust-lang/rust/pull/129019#issuecomment-2369361278 for the discussion CC @khuey @workingjubilee
This commit is contained in:
parent
3f99982c63
commit
49d1c3b433
@ -105,84 +105,7 @@ mod os {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
mod os {
|
||||
use super::DebuggerPresence;
|
||||
use crate::fs::File;
|
||||
use crate::io::Read;
|
||||
|
||||
pub(super) fn is_debugger_present() -> Option<DebuggerPresence> {
|
||||
// This function is crafted with the following goals:
|
||||
// * Memory efficiency: It avoids crashing the panicking process due to
|
||||
// out-of-memory (OOM) conditions by not using large heap buffers or
|
||||
// allocating significant stack space, which could lead to stack overflow.
|
||||
// * Minimal binary size: The function uses a minimal set of facilities
|
||||
// from the standard library to avoid increasing the resulting binary size.
|
||||
//
|
||||
// To achieve these goals, the function does not use `[std::io::BufReader]`
|
||||
// and instead reads the file byte by byte using a sliding window approach.
|
||||
// It's important to note that the "/proc/self/status" pseudo-file is synthesized
|
||||
// by the Virtual File System (VFS), meaning it is not read from a slow or
|
||||
// non-volatile storage medium so buffering might not be as beneficial because
|
||||
// all data is read from memory, though this approach does incur a syscall for
|
||||
// each byte read.
|
||||
//
|
||||
// We cannot make assumptions about the file size or the position of the
|
||||
// target prefix ("TracerPid:"), so the function does not use
|
||||
// `[std::fs::read_to_string]` thus not employing UTF-8 to ASCII checking,
|
||||
// conversion, or parsing as we're looking for an ASCII prefix.
|
||||
//
|
||||
// These condiderations make the function deviate from the familiar concise pattern
|
||||
// of searching for a string in a text file.
|
||||
|
||||
fn read_byte(file: &mut File) -> Option<u8> {
|
||||
let mut buffer = [0];
|
||||
file.read_exact(&mut buffer).ok()?;
|
||||
Some(buffer[0])
|
||||
}
|
||||
|
||||
// The ASCII prefix of the datum we're interested in.
|
||||
const TRACER_PID: &[u8] = b"TracerPid:\t";
|
||||
|
||||
let mut file = File::open("/proc/self/status").ok()?;
|
||||
let mut matched = 0;
|
||||
|
||||
// Look for the `TRACER_PID` prefix.
|
||||
while let Some(byte) = read_byte(&mut file) {
|
||||
if byte == TRACER_PID[matched] {
|
||||
matched += 1;
|
||||
if matched == TRACER_PID.len() {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
matched = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Was the prefix found?
|
||||
if matched != TRACER_PID.len() {
|
||||
return None;
|
||||
}
|
||||
|
||||
// It was; get the ASCII representation of the first digit
|
||||
// of the PID. That is enough to see if there is a debugger
|
||||
// attached as the kernel does not pad the PID on the left
|
||||
// with the leading zeroes.
|
||||
let byte = read_byte(&mut file)?;
|
||||
if byte.is_ascii_digit() && byte != b'0' {
|
||||
Some(DebuggerPresence::Detected)
|
||||
} else {
|
||||
Some(DebuggerPresence::NotDetected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(any(
|
||||
target_os = "windows",
|
||||
target_vendor = "apple",
|
||||
target_os = "freebsd",
|
||||
target_os = "linux"
|
||||
)))]
|
||||
#[cfg(not(any(target_os = "windows", target_vendor = "apple", target_os = "freebsd")))]
|
||||
mod os {
|
||||
pub(super) fn is_debugger_present() -> Option<super::DebuggerPresence> {
|
||||
None
|
||||
|
Loading…
Reference in New Issue
Block a user