2019-08-23 11:56:54 -07:00
|
|
|
namespace System.Diagnostics
|
|
|
|
{
|
2021-05-17 15:01:49 +02:00
|
|
|
static class Debug
|
2019-08-23 11:56:54 -07:00
|
|
|
{
|
|
|
|
#if !DEBUG
|
|
|
|
[SkipCall]
|
|
|
|
#endif
|
2020-09-04 08:09:04 -07:00
|
|
|
public static void Assert(bool condition, String error = Compiler.CallerExpression[0], String filePath = Compiler.CallerFilePath, int line = Compiler.CallerLineNum)
|
2019-08-23 11:56:54 -07:00
|
|
|
{
|
|
|
|
if (!condition)
|
2020-09-04 08:09:04 -07:00
|
|
|
{
|
2024-12-02 12:15:01 -05:00
|
|
|
if ((!Compiler.IsComptime) && (Runtime.CheckAssertError != null) && (Runtime.CheckAssertError(.Debug, error, filePath, line) == .Ignore))
|
2022-02-11 08:12:30 -05:00
|
|
|
return;
|
2024-03-16 07:23:29 -04:00
|
|
|
#if !BF_RUNTIME_REDUCED
|
|
|
|
String failStr = scope .()..Append("Assert failed: ", error, " at line ");
|
|
|
|
line.ToString(failStr);
|
|
|
|
failStr.Append(" in ", filePath);
|
2020-09-04 08:09:04 -07:00
|
|
|
Internal.FatalError(failStr, 1);
|
2024-03-16 07:23:29 -04:00
|
|
|
#else
|
|
|
|
Internal.FatalError("Assert failed", 1);
|
|
|
|
#endif
|
2020-09-04 08:09:04 -07:00
|
|
|
}
|
2019-08-23 11:56:54 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#if !DEBUG
|
|
|
|
[SkipCall]
|
|
|
|
#endif
|
2025-01-14 10:16:46 -08:00
|
|
|
public static void FatalError(StringView msg = "Fatal error encountered", String filePath = Compiler.CallerFilePath, int line = Compiler.CallerLineNum)
|
2019-08-23 11:56:54 -07:00
|
|
|
{
|
2024-03-16 07:23:29 -04:00
|
|
|
String failStr = scope .()..Append(msg, " at line ");
|
|
|
|
line.ToString(failStr);
|
|
|
|
failStr.Append(" in ", filePath);
|
2020-09-04 08:09:04 -07:00
|
|
|
Internal.FatalError(failStr, 1);
|
2019-08-23 11:56:54 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#if !DEBUG
|
|
|
|
[SkipCall]
|
|
|
|
#endif
|
|
|
|
public static void AssertNotStack(Object obj)
|
|
|
|
{
|
|
|
|
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
|
2020-03-09 06:34:16 -07:00
|
|
|
if ((obj != null) && (obj.[Friend]GetFlags() & 8 != 0))
|
2019-08-23 11:56:54 -07:00
|
|
|
Internal.FatalError("Assert failed", 1);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2025-02-18 09:51:16 -08:00
|
|
|
#if !BF_RUNTIME_DISABLE
|
|
|
|
[CallingConvention(.Cdecl)]
|
|
|
|
static extern void Write(char8* str, int strLen);
|
|
|
|
[CallingConvention(.Cdecl)]
|
|
|
|
static extern void Write(int val);
|
|
|
|
#else
|
2025-02-18 09:26:34 -08:00
|
|
|
static void Write(char8* str, int strLen)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
static void Write(int val)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
#endif
|
2019-08-23 11:56:54 -07:00
|
|
|
|
2020-03-25 09:17:53 -07:00
|
|
|
public static void Write(String line)
|
|
|
|
{
|
|
|
|
Write(line.Ptr, line.Length);
|
|
|
|
}
|
|
|
|
|
2021-11-02 09:56:31 -07:00
|
|
|
public static void Write(StringView sv)
|
|
|
|
{
|
|
|
|
Write(sv.[Friend]mPtr, sv.[Friend]mLength);
|
|
|
|
}
|
|
|
|
|
2025-01-14 10:16:46 -08:00
|
|
|
public static void Write(StringView fmt, params Span<Object> args)
|
2020-03-25 09:17:53 -07:00
|
|
|
{
|
2020-08-31 07:29:26 -07:00
|
|
|
String str = scope String(4096);
|
2020-03-25 09:17:53 -07:00
|
|
|
str.AppendF(fmt, params args);
|
|
|
|
Write(str);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void Write(Object obj)
|
|
|
|
{
|
2020-08-31 07:29:26 -07:00
|
|
|
String str = scope String(4096);
|
2020-03-25 09:17:53 -07:00
|
|
|
obj.ToString(str);
|
|
|
|
Write(str);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void WriteLine()
|
|
|
|
{
|
2020-10-08 12:48:24 -07:00
|
|
|
Write((char8*)"\n", 1);
|
2020-03-25 09:17:53 -07:00
|
|
|
}
|
|
|
|
|
2019-08-23 11:56:54 -07:00
|
|
|
public static void WriteLine(StringView line)
|
|
|
|
{
|
2022-01-06 22:10:52 +01:00
|
|
|
String lineStr = scope String(Math.Min(line.Length + 1, 4096));
|
2020-08-31 07:29:26 -07:00
|
|
|
lineStr.Append(line);
|
|
|
|
lineStr.Append('\n');
|
|
|
|
Write(lineStr.Ptr, lineStr.Length);
|
2019-08-23 11:56:54 -07:00
|
|
|
}
|
|
|
|
|
2025-01-14 10:16:46 -08:00
|
|
|
public static void WriteLine(StringView strFormat, params Span<Object> args)
|
2019-08-23 11:56:54 -07:00
|
|
|
{
|
2020-08-31 07:29:26 -07:00
|
|
|
String paramStr = scope String(4096);
|
2019-08-23 11:56:54 -07:00
|
|
|
paramStr.AppendF(strFormat, params args);
|
|
|
|
paramStr.Append('\n');
|
|
|
|
Write(paramStr.Ptr, paramStr.Length);
|
|
|
|
}
|
2020-10-10 07:08:30 -07:00
|
|
|
|
|
|
|
static bool gIsDebuggerPresent = IsDebuggerPresent;
|
2024-03-16 07:23:29 -04:00
|
|
|
[LinkName("IsDebuggerPresent"), CallingConvention(.Stdcall), Import("kernel32.lib")]
|
2020-10-10 07:08:30 -07:00
|
|
|
static extern int32 Internal_IsDebuggerPresent();
|
|
|
|
|
|
|
|
public static bool IsDebuggerPresent
|
|
|
|
{
|
|
|
|
#if BF_PLATFORM_WINDOWS
|
|
|
|
get => gIsDebuggerPresent = Internal_IsDebuggerPresent() != 0;
|
|
|
|
#else
|
|
|
|
get => false;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
[Intrinsic("debugtrap")]
|
|
|
|
public static extern void Break();
|
|
|
|
|
|
|
|
[NoDebug]
|
|
|
|
public static void SafeBreak()
|
|
|
|
{
|
|
|
|
if (gIsDebuggerPresent)
|
|
|
|
Break();
|
|
|
|
}
|
2021-12-20 09:39:39 -05:00
|
|
|
|
|
|
|
public static void WriteMemory(Span<uint8> mem)
|
|
|
|
{
|
|
|
|
String str = scope .();
|
|
|
|
for (int i < mem.Length)
|
|
|
|
{
|
|
|
|
if ((i != 0) && (i % 16 == 0))
|
|
|
|
str.Append('\n');
|
|
|
|
str.AppendF($" {mem.[Friend]mPtr[i]:X2}");
|
|
|
|
}
|
|
|
|
str.Append('\n');
|
|
|
|
Write(str);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void WriteMemory<T>(T result)
|
|
|
|
{
|
|
|
|
#unwarn
|
|
|
|
WriteMemory(.((.)&result, sizeof(T)));
|
|
|
|
}
|
2019-08-23 11:56:54 -07:00
|
|
|
}
|
|
|
|
}
|