asan debug callback
This commit is contained in:
parent
3d110a1da5
commit
7ba8c7f3bf
@ -176,7 +176,8 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
//- Address sanitization
|
//- Address sanitization
|
||||||
#if IsAsanEnabled
|
#if IsAsanEnabled && IsCpu
|
||||||
|
void __asan_set_error_report_callback(void (*callback)(char *));
|
||||||
void __asan_poison_memory_region(void const volatile *, size_t);
|
void __asan_poison_memory_region(void const volatile *, size_t);
|
||||||
void __asan_unpoison_memory_region(void const volatile *, size_t);
|
void __asan_unpoison_memory_region(void const volatile *, size_t);
|
||||||
#define AsanPoison(addr, size) __asan_poison_memory_region((addr), (size))
|
#define AsanPoison(addr, size) __asan_poison_memory_region((addr), (size))
|
||||||
@ -281,20 +282,20 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Linked list helper macros
|
//~ Linked list helper macros
|
||||||
|
|
||||||
// Taken from the rad debugger
|
// Taken from the RAD Debugger
|
||||||
// https://github.com/EpicGamesExt/raddebugger/blob/be5634c44867a2e31f6a109df5e574930992df01/src/base/base_core.h#L239
|
// https://github.com/EpicGamesExt/raddebugger/blob/be5634c44867a2e31f6a109df5e574930992df01/src/base/base_core.h#L239
|
||||||
|
|
||||||
#define CheckNil(nil,p) ((p) == 0 || (p) == nil)
|
#define CheckNil(nil,p) ((p) == 0 || (p) == nil)
|
||||||
#define SetNil(nil,p) ((p) = nil)
|
#define SetNil(nil,p) ((p) = nil)
|
||||||
|
|
||||||
//- Singly linked stack (first & next pointers)
|
//- Singly linked stack
|
||||||
|
|
||||||
#define SllStackPushN(f,n,next) ((n)->next=(f), (f)=(n))
|
#define SllStackPushN(f,n,next) ((n)->next=(f), (f)=(n))
|
||||||
#define SllStackPopN(f,next) ((f)=(f)->next)
|
#define SllStackPopN(f,next) ((f)=(f)->next)
|
||||||
#define SllStackPush(f,n) SllStackPushN(f,n,next)
|
#define SllStackPush(f,n) SllStackPushN(f,n,next)
|
||||||
#define SllStackPop(f) SllStackPopN(f,next)
|
#define SllStackPop(f) SllStackPopN(f,next)
|
||||||
|
|
||||||
//- Singly linked queue (first, last, & next pointers)
|
//- Singly linked queue
|
||||||
|
|
||||||
#define SllQueuePushNZ(nil,f,l,n,next) \
|
#define SllQueuePushNZ(nil,f,l,n,next) \
|
||||||
( \
|
( \
|
||||||
@ -324,7 +325,7 @@
|
|||||||
#define SllQueuePopN(f,l,next) SllQueuePopNZ(0,f,l,next)
|
#define SllQueuePopN(f,l,next) SllQueuePopNZ(0,f,l,next)
|
||||||
#define SllQueuePop(f,l) SllQueuePopNZ(0,f,l,next)
|
#define SllQueuePop(f,l) SllQueuePopNZ(0,f,l,next)
|
||||||
|
|
||||||
//- Doubly linked stack (first, next, & prev pointers)
|
//- Doubly linked stack
|
||||||
|
|
||||||
#define DllStackPushNPZ(nil,f,n,next,prev) \
|
#define DllStackPushNPZ(nil,f,n,next,prev) \
|
||||||
( \
|
( \
|
||||||
@ -359,7 +360,7 @@
|
|||||||
#define DllStackRemoveNP(f,n,next,prev) DllStackRemoveNPZ(0,f,n,next,prev)
|
#define DllStackRemoveNP(f,n,next,prev) DllStackRemoveNPZ(0,f,n,next,prev)
|
||||||
#define DllStackRemove(f,n) DllStackRemoveNPZ(0,f,n,next,prev)
|
#define DllStackRemove(f,n) DllStackRemoveNPZ(0,f,n,next,prev)
|
||||||
|
|
||||||
//- Doubly linked queue (first, last, next, & prev pointers)
|
//- Doubly linked queue
|
||||||
|
|
||||||
#define DllQueueInsertNPZ(nil,f,l,p,n,next,prev) \
|
#define DllQueueInsertNPZ(nil,f,l,p,n,next,prev) \
|
||||||
( \
|
( \
|
||||||
@ -836,7 +837,7 @@ Inline u64 MixU64s(u64 seed_a, u64 seed_b)
|
|||||||
void LoadApi(ApiDesc api);
|
void LoadApi(ApiDesc api);
|
||||||
void Echo(String msg);
|
void Echo(String msg);
|
||||||
b32 Panic(String msg);
|
b32 Panic(String msg);
|
||||||
b32 DebugBreakPrompt(String title, String msg);
|
b32 DebugActionPrompt(String title, String msg);
|
||||||
Callstack CaptureCallstack(u64 skip_frames);
|
Callstack CaptureCallstack(u64 skip_frames);
|
||||||
b32 IsRunningInDebugger(void);
|
b32 IsRunningInDebugger(void);
|
||||||
b32 IsRunningInWine(void);
|
b32 IsRunningInWine(void);
|
||||||
|
|||||||
@ -146,7 +146,7 @@ b32 Panic(String msg)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
b32 DebugBreakPrompt(String title, String msg)
|
b32 DebugActionPrompt(String title, String msg)
|
||||||
{
|
{
|
||||||
LogInfoF("[DEBUG BREAK PROMPT]: %F", FmtString(msg));
|
LogInfoF("[DEBUG BREAK PROMPT]: %F", FmtString(msg));
|
||||||
TempArena scratch = BeginScratchNoConflict();
|
TempArena scratch = BeginScratchNoConflict();
|
||||||
@ -517,19 +517,54 @@ LogEventsArray GetLogEvents(void)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Asan
|
||||||
|
|
||||||
|
void W32_AsanCallback(char *report_cstr)
|
||||||
|
{
|
||||||
|
i32 result = 0;
|
||||||
|
{
|
||||||
|
b32 is_debug = IsRunningInDebugger();
|
||||||
|
i32 mb_result = 0;
|
||||||
|
{
|
||||||
|
u32 mb_flags = MB_SETFOREGROUND | MB_ICONWARNING;
|
||||||
|
if (is_debug)
|
||||||
|
{
|
||||||
|
mb_flags |= MB_CANCELTRYCONTINUE;
|
||||||
|
}
|
||||||
|
mb_result = MessageBoxExA(0, report_cstr, "Address sanitization error", mb_flags, 0);
|
||||||
|
}
|
||||||
|
if (mb_result == IDCANCEL)
|
||||||
|
{
|
||||||
|
ExitProcess(1);
|
||||||
|
}
|
||||||
|
result = is_debug && mb_result != IDCONTINUE;
|
||||||
|
}
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
DEBUGBREAK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Main
|
//~ Main
|
||||||
|
|
||||||
i32 W32_Main(void)
|
i32 W32_Main(void)
|
||||||
{
|
{
|
||||||
|
#if IsAsanEnabled
|
||||||
|
{
|
||||||
|
__asan_set_error_report_callback(W32_AsanCallback);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Init time
|
// Init time
|
||||||
{
|
{
|
||||||
LARGE_INTEGER qpf;
|
LARGE_INTEGER qpf = Zi;
|
||||||
QueryPerformanceFrequency(&qpf);
|
QueryPerformanceFrequency(&qpf);
|
||||||
W32.ns_per_qpc = 1000000000 / qpf.QuadPart;
|
W32.ns_per_qpc = 1000000000 / qpf.QuadPart;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
LARGE_INTEGER qpc;
|
LARGE_INTEGER qpc = Zi;
|
||||||
QueryPerformanceCounter(&qpc);
|
QueryPerformanceCounter(&qpc);
|
||||||
W32.timer_start_qpc = qpc.QuadPart;
|
W32.timer_start_qpc = qpc.QuadPart;
|
||||||
}
|
}
|
||||||
@ -552,20 +587,19 @@ i32 W32_Main(void)
|
|||||||
W32.panic_event = CreateEventW(0, 1, 0, 0);
|
W32.panic_event = CreateEventW(0, 1, 0, 0);
|
||||||
W32.exit_event = CreateEventW(0, 1, 0, 0);
|
W32.exit_event = CreateEventW(0, 1, 0, 0);
|
||||||
|
|
||||||
W32.main_thread_id = GetCurrentThreadId();
|
|
||||||
SetThreadDescription(GetCurrentThread(), L"Main thread");
|
|
||||||
|
|
||||||
// Query system info
|
// Query system info
|
||||||
GetSystemInfo(&W32.info);
|
GetSystemInfo(&W32.info);
|
||||||
|
|
||||||
|
// Init main thread
|
||||||
|
W32_InitCurrentThread(Lit("Main"));
|
||||||
|
W32.main_thread_id = GetCurrentThreadId();
|
||||||
|
SetThreadDescription(GetCurrentThread(), L"Main thread");
|
||||||
|
|
||||||
// Setup logging memory
|
// Setup logging memory
|
||||||
W32.logs_arena = AcquireArena(Gibi(64));
|
W32.logs_arena = AcquireArena(Gibi(64));
|
||||||
W32.log_events_arena = AcquireArena(Gibi(64));
|
W32.log_events_arena = AcquireArena(Gibi(64));
|
||||||
W32.readable_log_events = ArenaNext(W32.logs_arena, LogEvent);
|
W32.readable_log_events = ArenaNext(W32.logs_arena, LogEvent);
|
||||||
|
|
||||||
// Init main thread
|
|
||||||
W32_InitCurrentThread(Lit("Main"));
|
|
||||||
|
|
||||||
// Get raw args from command line
|
// Get raw args from command line
|
||||||
Arena *perm = PermArena();
|
Arena *perm = PermArena();
|
||||||
String cmdline_str = Zi;
|
String cmdline_str = Zi;
|
||||||
|
|||||||
@ -142,6 +142,11 @@ String W32_StringFromError(Arena *arena, i32 code);
|
|||||||
void W32_LogEventToFile(LogEvent *ev, HANDLE file);
|
void W32_LogEventToFile(LogEvent *ev, HANDLE file);
|
||||||
void W32_Log(i32 level, String msg);
|
void W32_Log(i32 level, String msg);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Asan
|
||||||
|
|
||||||
|
void W32_AsanCallback(char *report_cstr);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Main
|
//~ Main
|
||||||
|
|
||||||
|
|||||||
@ -4008,7 +4008,7 @@ void G_D12_DebugCallback(
|
|||||||
{
|
{
|
||||||
String description = StringFromCstrNoLimit((char *)description_cstr);
|
String description = StringFromCstrNoLimit((char *)description_cstr);
|
||||||
Echo(StringF(scratch.arena, "[D3D12 DEBUG] %F\n", FmtString(description)));
|
Echo(StringF(scratch.arena, "[D3D12 DEBUG] %F\n", FmtString(description)));
|
||||||
if (DebugBreakPrompt(Lit("D3D12 Debug Break"), description))
|
if (DebugActionPrompt(Lit("D3D12 Debug Break"), description))
|
||||||
{
|
{
|
||||||
DEBUGBREAK;
|
DEBUGBREAK;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -405,6 +405,15 @@ void M_BuildEntryPoint(WaveLaneCtx *lane)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Asan
|
||||||
|
{
|
||||||
|
CommandlineArg arg = CommandlineArgFromName(Lit("asan"));
|
||||||
|
if (arg.exists)
|
||||||
|
{
|
||||||
|
M.cmdline.asan = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (lane->idx == 0)
|
if (lane->idx == 0)
|
||||||
{
|
{
|
||||||
if (M.cmdline.target_compiler == M_CompilerKind_Msvc)
|
if (M.cmdline.target_compiler == M_CompilerKind_Msvc)
|
||||||
@ -425,6 +434,11 @@ void M_BuildEntryPoint(WaveLaneCtx *lane)
|
|||||||
M_EchoLine(Lit("[Debug build]"));
|
M_EchoLine(Lit("[Debug build]"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (M.cmdline.asan)
|
||||||
|
{
|
||||||
|
M_EchoLine(Lit("[ASAN]"));
|
||||||
|
}
|
||||||
|
|
||||||
M_EchoLine(StringF(perm, "Building layer \"%F\"", FmtString(M.cmdline.leaf_layer_name)));
|
M_EchoLine(StringF(perm, "Building layer \"%F\"", FmtString(M.cmdline.leaf_layer_name)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -455,7 +469,15 @@ void M_BuildEntryPoint(WaveLaneCtx *lane)
|
|||||||
PushStringToList(perm, &cp.defs, Lit("-DIsConsoleApp=0"));
|
PushStringToList(perm, &cp.defs, Lit("-DIsConsoleApp=0"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (M.cmdline.asan)
|
||||||
|
{
|
||||||
|
PushStringToList(perm, &cp.defs, Lit("-DIsAsanEnabled=1"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
PushStringToList(perm, &cp.defs, Lit("-DIsAsanEnabled=0"));
|
PushStringToList(perm, &cp.defs, Lit("-DIsAsanEnabled=0"));
|
||||||
|
}
|
||||||
|
|
||||||
PushStringToList(perm, &cp.defs, Lit("-DIsDebinfoEnabled=1"));
|
PushStringToList(perm, &cp.defs, Lit("-DIsDebinfoEnabled=1"));
|
||||||
PushStringToList(perm, &cp.defs, Lit("-DIsDeveloperModeEnabled=1"));
|
PushStringToList(perm, &cp.defs, Lit("-DIsDeveloperModeEnabled=1"));
|
||||||
PushStringToList(perm, &cp.defs, Lit("-DIsTestingEnabled=0"));
|
PushStringToList(perm, &cp.defs, Lit("-DIsTestingEnabled=0"));
|
||||||
@ -481,6 +503,19 @@ void M_BuildEntryPoint(WaveLaneCtx *lane)
|
|||||||
PushStringToList(perm, &cp.compiler_only_flags_msvc, Lit("-Od"));
|
PushStringToList(perm, &cp.compiler_only_flags_msvc, Lit("-Od"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (M.cmdline.asan)
|
||||||
|
{
|
||||||
|
PushStringToList(perm, &cp.compiler_only_flags_msvc, Lit("-fsanitize=address"));
|
||||||
|
// PushStringToList(perm, &cp.compiler_only_flags_msvc, Lit("-fsanitize-address-use-after-return"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!M.cmdline.release)
|
||||||
|
{
|
||||||
|
PushStringToList(perm, &cp.compiler_only_flags_msvc, Lit("-RTCsu"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Export debug info separately for release builds
|
// TODO: Export debug info separately for release builds
|
||||||
PushStringToList(perm, &cp.flags_msvc, Lit("-DEBUG:FULL"));
|
PushStringToList(perm, &cp.flags_msvc, Lit("-DEBUG:FULL"));
|
||||||
PushStringToList(perm, &cp.compiler_only_flags_msvc, Lit("-Z7"));
|
PushStringToList(perm, &cp.compiler_only_flags_msvc, Lit("-Z7"));
|
||||||
|
|||||||
@ -141,6 +141,7 @@ Struct(M_CommandLine)
|
|||||||
{
|
{
|
||||||
b32 release;
|
b32 release;
|
||||||
b32 console;
|
b32 console;
|
||||||
|
b32 asan;
|
||||||
String leaf_layer_name;
|
String leaf_layer_name;
|
||||||
M_PlatformKind target_platform;
|
M_PlatformKind target_platform;
|
||||||
M_CompilerKind target_compiler;
|
M_CompilerKind target_compiler;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user