47 return IsDebuggerPresent ();
66#include <sys/sysctl.h>
78 struct kinfo_proc info;
84 info.kp_proc.p_flag = 0;
91 mib[2] = KERN_PROC_PID;
97 sysctl (mib,
sizeof (mib) /
sizeof (*mib), &info, &size, NULL, 0);
100 return ((info.kp_proc.p_flag & P_TRACED) != 0);
115#define _WIN32_WINNT 0x0400
120#define vsnprintf _vsnprintf
121#define snprintf _snprintf
125#include <mach/mach_init.h>
126#include <mach/mach_time.h>
130#define THREAD_ALLOC_WATCH 0
132#if THREAD_ALLOC_WATCH
133mach_port_t watchThreadID = 0;
138AssertionHandler gAssertionHandler =
nullptr;
139AssertionHandler gPreAssertionHook =
nullptr;
140DebugPrintLogger gDebugPrintLogger =
nullptr;
143static const int kDebugPrintfBufferSize = 10000;
144static bool neverDebugger =
false;
149static void initNeverDebugger ()
155 neverDebugger =
true;
161static void printDebugString (
const char*
string)
166 if (gDebugPrintLogger)
168 gDebugPrintLogger (
string);
172#if SMTG_OS_MACOS || defined(__MINGW32__)
173 fprintf (stderr,
"%s",
string);
175 OutputDebugStringA (
string);
183void FDebugPrint (
const char* format, ...)
185 char string[kDebugPrintfBufferSize];
188 vsnprintf (
string, kDebugPrintfBufferSize, format, marker);
190 printDebugString (
string);
196void FDebugBreak (
const char* format, ...)
198 char string[kDebugPrintfBufferSize];
201 vsnprintf (
string, kDebugPrintfBufferSize, format, marker);
203 printDebugString (
string);
207 if (gPreAssertionHook)
209 gPreAssertionHook (
string);
212 initNeverDebugger ();
220 bool breakIntoDebugger =
true;
221 if (gAssertionHandler && gAssertionHandler (
string) ==
false)
223 breakIntoDebugger =
false;
226 if (breakIntoDebugger)
228#if SMTG_OS_WINDOWS && _MSC_VER
230#elif SMTG_OS_MACOS && __arm64__
233#elif __ppc64__ || __ppc__ || __arm__
234 kill (getpid (), SIGINT);
235#elif __i386__ || __x86_64__
237 __asm__
volatile (
"int3");
245void FPrintLastError (
const char* file,
int line)
248 LPVOID lpMessageBuffer =
nullptr;
249 FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
nullptr,
250 GetLastError (), MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
251 (LPSTR)&lpMessageBuffer, 0,
nullptr);
252 FDebugPrint (
"%s(%d) : %s\n", file, line, lpMessageBuffer);
253 LocalFree (lpMessageBuffer);
260 FDebugPrint (
"%s(%d) : Errno %d\n", file, line, errno);
267void*
operator new (
size_t size,
int,
const char* file,
int line)
269#if THREAD_ALLOC_WATCH
270 mach_port_t threadID = mach_thread_self ();
271 if (watchThreadID == threadID)
273 FDebugPrint (
"Watched Thread Allocation : %s (Line:%d)\n", file ? file :
"Unknown", line);
278 return ::operator
new (
size);
282 FDebugPrint (
"bad_alloc exception : %s (Line:%d)", file ? file :
"Unknown", line);
288void*
operator new[] (
size_t size,
int,
const char* file,
int line)
290#if THREAD_ALLOC_WATCH
291 mach_port_t threadID = mach_thread_self ();
292 if (watchThreadID == threadID)
294 FDebugPrint (
"Watched Thread Allocation : %s (Line:%d)\n", file ? file :
"Unknown", line);
299 return ::operator
new[] (
size);
303 FDebugPrint (
"bad_alloc exception : %s (Line:%d)", file ? file :
"Unknown", line);
309void operator delete (
void* p,
int,
const char* file,
int line)
313 ::operator
delete (p);
317void operator delete[] (
void* p,
int,
const char* file,
int line)
321 ::operator
delete[] (p);
328static bool smtg_unit_testing_active =
false;
331bool isSmtgUnitTesting ()
333 return smtg_unit_testing_active;
337void setSmtgUnitTesting ()
339 smtg_unit_testing_active =
true;
bool AmIBeingDebugged()
Returns true if a debugger is attached.