[build] Skips RemoteExecuted bases tests on monodroid
[mono-project.git] / mono / utils / mono-utils-debug.c
blobacc4115c4b36b4cbc9ced42270cbeb45b1d47fe1
1 /* mono-utils-debug.c
3 * Copyright 2018 Microsoft
4 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
5 */
7 #include <config.h>
8 #include <glib.h>
9 #include "mono-utils-debug.h"
11 #if defined (_WIN32)
13 #include <windows.h>
15 gboolean
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;
24 #else
26 #include <unistd.h>
27 #include <errno.h>
28 #include <fcntl.h>
29 #if defined (__APPLE__)
30 #include <sys/sysctl.h>
31 #endif
32 #if defined (__NetBSD__)
33 #include <kvm.h>
34 #endif
36 static gboolean
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);
55 if (status_fd == -1)
56 return FALSE;
58 char buf [4098];
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);
62 close (status_fd);
63 static const char TracerPid [ ] = "\nTracerPid:";
64 if (num_read <= sizeof (TracerPid))
65 return FALSE;
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");
74 if (!kd)
75 return FALSE;
76 int count = 0;
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);
79 kvm_close (kd);
80 return traced;
82 #else
83 return FALSE; // FIXME Other operating systems.
84 #endif
87 // Cache because it is slow.
88 static gchar mono_is_usermode_native_debugger_present_cache; // 0:uninitialized 1:true 2:false
90 gboolean
91 mono_is_usermode_native_debugger_present (void)
93 if (mono_is_usermode_native_debugger_present_cache == 0) {
94 int er = errno;
95 mono_is_usermode_native_debugger_present_cache = mono_is_usermode_native_debugger_present_slow () ? 1 : 2;
96 errno = er;
98 return mono_is_usermode_native_debugger_present_cache == 1;
101 #endif // fast uncached Window vs. slow cached the rest
103 #if 0 // test
106 #ifdef _MSC_VER
107 __cdecl
108 #endif
109 main ()
111 printf ("mono_usermode_native_debugger_present:%d\n", mono_is_usermode_native_debugger_present ());
114 #endif