3 * Copyright 2018 Microsoft
4 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
9 #include "mono-utils-debug.h"
16 mono_is_usermode_native_debugger_present (void)
18 // This is just a few instructions and no syscall. It is very fast.
19 // Kernel debugger is detected otherwise and is also useful for usermode debugging.
20 // Mono managed debugger is detected otherwise.
21 return IsDebuggerPresent () ? TRUE
: FALSE
;
29 #if defined (__APPLE__)
30 #include <sys/sysctl.h>
32 #if defined (__NetBSD__)
37 mono_is_usermode_native_debugger_present_slow (void)
38 // PAL_IsDebuggerPresent
39 // based closely on with some local cleanup:
40 // https://github.com/dotnet/coreclr/blob/master/src/pal/src/init/pal.cpp
41 // https://raw.githubusercontent.com/dotnet/coreclr/f1c9dac3e2db2397e01cd2da3e8aaa4f81a80013/src/pal/src/init/pal.cpp
43 #if defined (__APPLE__)
45 struct kinfo_proc info
;
46 size_t size
= sizeof (info
);
47 memset (&info
, 0, size
);
48 int mib
[4] = { CTL_KERN
, KERN_PROC
, KERN_PROC_PID
, getpid () };
49 return sysctl (mib
, sizeof (mib
) / sizeof (*mib
), &info
, &size
, NULL
, 0) == 0
50 && (info
.kp_proc
.p_flag
& P_TRACED
) != 0;
52 #elif defined (__linux__)
54 int const status_fd
= open ("/proc/self/status", O_RDONLY
);
59 buf
[0] = '\n'; // consider if the first line
60 buf
[1] = 0; // clear out garbage
61 ssize_t
const num_read
= read (status_fd
, &buf
[1], sizeof(buf
) - 2);
63 static const char TracerPid
[ ] = "\nTracerPid:";
64 if (num_read
<= sizeof (TracerPid
))
67 buf
[num_read
+ 1] = 0;
68 char const * const tracer_pid
= strstr (buf
, TracerPid
);
69 return tracer_pid
&& atoi (tracer_pid
+ sizeof (TracerPid
) - 1);
71 #elif defined (__NetBSD__)
73 kvm_t
* const kd
= kvm_open (NULL
, NULL
, NULL
, KVM_NO_FILES
, "kvm_open");
77 struct kinfo_proc
const * const info
= kvm_getprocs (kd
, KERN_PROC_PID
, getpid (), &count
);
78 gboolean
const traced
= info
&& count
> 0 && (info
->kp_proc
.p_slflag
& PSL_TRACED
);
83 return FALSE
; // FIXME Other operating systems.
87 // Cache because it is slow.
88 static gchar mono_is_usermode_native_debugger_present_cache
; // 0:uninitialized 1:true 2:false
91 mono_is_usermode_native_debugger_present (void)
93 if (mono_is_usermode_native_debugger_present_cache
== 0) {
95 mono_is_usermode_native_debugger_present_cache
= mono_is_usermode_native_debugger_present_slow () ? 1 : 2;
98 return mono_is_usermode_native_debugger_present_cache
== 1;
101 #endif // fast uncached Window vs. slow cached the rest
111 printf ("mono_usermode_native_debugger_present:%d\n", mono_is_usermode_native_debugger_present ());