4#include "Stroika/Foundation/StroikaPreComp.h"
6#if __cpp_lib_debugging >= 202403L
10#if qStroika_Foundation_Common_Platform_POSIX
15#if defined(__APPLE__) && defined(__MACH__)
16#include <sys/sysctl.h>
21#include <sys/ptrace.h>
22#elif qStroika_Foundation_Common_Platform_Windows
25#include "Stroika/Foundation/Math/Common.h"
32#define __has_builtin(x) 0
35#if qStroika_Foundation_Common_Platform_Linux
38 bool DebuggerIsAttached_ ()
43 const int status_fd = ::open (
"/proc/self/status", O_RDONLY);
46 num_read = ::read (status_fd, buf,
sizeof (buf) - 1);
52 constexpr char kTacerPidString_[] =
"TracerPid:";
53 const auto tracer_pid_ptr = ::strstr (buf, kTacerPidString_);
54 if (tracer_pid_ptr ==
nullptr)
56 for (
const char* characterPtr = tracer_pid_ptr +
sizeof (kTacerPidString_) - 1; characterPtr <= buf + num_read; ++characterPtr) {
57 if (::isspace (*characterPtr))
60 return ::isdigit (*characterPtr) != 0 && *characterPtr !=
'0';
67#if qStroika_Foundation_Common_Platform_MacOS
73 bool DebuggerIsAttached_ ()
80 int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid ()};
81 size_t size =
sizeof (info);
82 [[maybe_unused]]
int junk = sysctl (mib,
sizeof (mib) /
sizeof (*mib), &info, &size, NULL, 0);
84 return (info.kp_proc.p_flag & P_TRACED) != 0;
94optional<bool> Debug::IsThisProcessBeingDebugged ()
96#if __cpp_lib_debugging >= 202403L
97 return std::is_debugger_present ();
99#if qStroika_Foundation_Common_Platform_Linux
100 return DebuggerIsAttached_ ();
102#if qStroika_Foundation_Common_Platform_MacOS
103 return DebuggerIsAttached_ ();
105#if qStroika_Foundation_Common_Platform_POSIX
108 return ptrace (PTRACE_TRACEME, 0, NULL, 0) == -1;
111#if qStroika_Foundation_Common_Platform_Windows
112 return ::IsDebuggerPresent ();
122void Debug::DropIntoDebuggerIfPresent ()
124 if (IsThisProcessBeingDebugged () ==
true) {
125#if __has_builtin(__builtin_trap) || defined(__GNUC__)
127#elif qStroika_Foundation_Common_Platform_POSIX
129#elif qStroika_Foundation_Common_Platform_Windows