@@ -105,84 +105,7 @@ mod os {
105105 }
106106}
107107
108- #[ cfg( target_os = "linux" ) ]
109- mod os {
110- use super :: DebuggerPresence ;
111- use crate :: fs:: File ;
112- use crate :: io:: Read ;
113-
114- pub ( super ) fn is_debugger_present ( ) -> Option < DebuggerPresence > {
115- // This function is crafted with the following goals:
116- // * Memory efficiency: It avoids crashing the panicking process due to
117- // out-of-memory (OOM) conditions by not using large heap buffers or
118- // allocating significant stack space, which could lead to stack overflow.
119- // * Minimal binary size: The function uses a minimal set of facilities
120- // from the standard library to avoid increasing the resulting binary size.
121- //
122- // To achieve these goals, the function does not use `[std::io::BufReader]`
123- // and instead reads the file byte by byte using a sliding window approach.
124- // It's important to note that the "/proc/self/status" pseudo-file is synthesized
125- // by the Virtual File System (VFS), meaning it is not read from a slow or
126- // non-volatile storage medium so buffering might not be as beneficial because
127- // all data is read from memory, though this approach does incur a syscall for
128- // each byte read.
129- //
130- // We cannot make assumptions about the file size or the position of the
131- // target prefix ("TracerPid:"), so the function does not use
132- // `[std::fs::read_to_string]` thus not employing UTF-8 to ASCII checking,
133- // conversion, or parsing as we're looking for an ASCII prefix.
134- //
135- // These condiderations make the function deviate from the familiar concise pattern
136- // of searching for a string in a text file.
137-
138- fn read_byte ( file : & mut File ) -> Option < u8 > {
139- let mut buffer = [ 0 ] ;
140- file. read_exact ( & mut buffer) . ok ( ) ?;
141- Some ( buffer[ 0 ] )
142- }
143-
144- // The ASCII prefix of the datum we're interested in.
145- const TRACER_PID : & [ u8 ] = b"TracerPid:\t " ;
146-
147- let mut file = File :: open ( "/proc/self/status" ) . ok ( ) ?;
148- let mut matched = 0 ;
149-
150- // Look for the `TRACER_PID` prefix.
151- while let Some ( byte) = read_byte ( & mut file) {
152- if byte == TRACER_PID [ matched] {
153- matched += 1 ;
154- if matched == TRACER_PID . len ( ) {
155- break ;
156- }
157- } else {
158- matched = 0 ;
159- }
160- }
161-
162- // Was the prefix found?
163- if matched != TRACER_PID . len ( ) {
164- return None ;
165- }
166-
167- // It was; get the ASCII representation of the first digit
168- // of the PID. That is enough to see if there is a debugger
169- // attached as the kernel does not pad the PID on the left
170- // with the leading zeroes.
171- let byte = read_byte ( & mut file) ?;
172- if byte. is_ascii_digit ( ) && byte != b'0' {
173- Some ( DebuggerPresence :: Detected )
174- } else {
175- Some ( DebuggerPresence :: NotDetected )
176- }
177- }
178- }
179-
180- #[ cfg( not( any(
181- target_os = "windows" ,
182- target_vendor = "apple" ,
183- target_os = "freebsd" ,
184- target_os = "linux"
185- ) ) ) ]
108+ #[ cfg( not( any( target_os = "windows" , target_vendor = "apple" , target_os = "freebsd" ) ) ) ]
186109mod os {
187110 pub ( super ) fn is_debugger_present ( ) -> Option < super :: DebuggerPresence > {
188111 None
0 commit comments