mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-06-15 00:22:23 -07:00
source-markup-defined auto-view-rules
This commit is contained in:
@@ -2077,6 +2077,26 @@ ctrl_initial_debug_info_path_from_module(Arena *arena, CTRL_Handle module_handle
|
||||
return result;
|
||||
}
|
||||
|
||||
internal String8
|
||||
ctrl_raddbg_data_from_module(Arena *arena, CTRL_Handle module_handle)
|
||||
{
|
||||
String8 result = {0};
|
||||
U64 hash = ctrl_hash_from_handle(module_handle);
|
||||
U64 slot_idx = hash%ctrl_state->module_image_info_cache.slots_count;
|
||||
U64 stripe_idx = slot_idx%ctrl_state->module_image_info_cache.stripes_count;
|
||||
CTRL_ModuleImageInfoCacheSlot *slot = &ctrl_state->module_image_info_cache.slots[slot_idx];
|
||||
CTRL_ModuleImageInfoCacheStripe *stripe = &ctrl_state->module_image_info_cache.stripes[stripe_idx];
|
||||
OS_MutexScopeR(stripe->rw_mutex) for(CTRL_ModuleImageInfoCacheNode *n = slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(ctrl_handle_match(n->module, module_handle))
|
||||
{
|
||||
result = push_str8_copy(arena, n->raddbg_data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Unwinding Functions
|
||||
|
||||
@@ -3582,6 +3602,7 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_
|
||||
U32 rdi_dbg_time = 0;
|
||||
Guid rdi_dbg_guid = {0};
|
||||
String8 rdi_dbg_path = str8_zero();
|
||||
String8 raddbg_data = str8_zero();
|
||||
ProfScope("unpack relevant PE info")
|
||||
{
|
||||
B32 is_valid = 1;
|
||||
@@ -3775,6 +3796,30 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: extract copy of module's raddbg data
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
U64 sec_array_off = opt_ext_off_range.max;
|
||||
U64 sec_count = file_header.section_count;
|
||||
COFF_SectionHeader *sec = push_array(scratch.arena, COFF_SectionHeader, sec_count);
|
||||
dmn_process_read(process.dmn_handle, r1u64(vaddr_range.min + sec_array_off, vaddr_range.min + sec_array_off + sec_count*sizeof(COFF_SectionHeader)), sec);
|
||||
Rng1U64 raddbg_section_voff_range = r1u64(0, 0);
|
||||
for EachIndex(idx, sec_count)
|
||||
{
|
||||
String8 section_name = str8_cstring(sec[idx].name);
|
||||
if(str8_match(section_name, str8_lit(".raddbg"), 0))
|
||||
{
|
||||
raddbg_section_voff_range.min = sec[idx].voff;
|
||||
raddbg_section_voff_range.max = sec[idx].voff + sec[idx].vsize;
|
||||
}
|
||||
}
|
||||
raddbg_data.size = dim_1u64(raddbg_section_voff_range);
|
||||
raddbg_data.str = push_array(arena, U8, raddbg_data.size);
|
||||
dmn_process_read(process.dmn_handle, r1u64(vaddr_range.min + raddbg_section_voff_range.min,
|
||||
vaddr_range.min + raddbg_section_voff_range.max), raddbg_data.str);
|
||||
scratch_end(scratch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3853,6 +3898,7 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_
|
||||
node->pdatas_count = pdatas_count;
|
||||
node->entry_point_voff = entry_point_voff;
|
||||
node->initial_debug_info_path = initial_debug_info_path;
|
||||
node->raddbg_data = raddbg_data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -593,6 +593,7 @@ struct CTRL_ModuleImageInfoCacheNode
|
||||
U64 entry_point_voff;
|
||||
Rng1U64 tls_vaddr_range;
|
||||
String8 initial_debug_info_path;
|
||||
String8 raddbg_data;
|
||||
};
|
||||
|
||||
typedef struct CTRL_ModuleImageInfoCacheSlot CTRL_ModuleImageInfoCacheSlot;
|
||||
@@ -891,6 +892,7 @@ internal PE_IntelPdata *ctrl_intel_pdata_from_module_voff(Arena *arena, CTRL_Han
|
||||
internal U64 ctrl_entry_point_voff_from_module(CTRL_Handle module_handle);
|
||||
internal Rng1U64 ctrl_tls_vaddr_range_from_module(CTRL_Handle module_handle);
|
||||
internal String8 ctrl_initial_debug_info_path_from_module(Arena *arena, CTRL_Handle module_handle);
|
||||
internal String8 ctrl_raddbg_data_from_module(Arena *arena, CTRL_Handle module_handle);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Unwinding Functions
|
||||
|
||||
@@ -1,245 +0,0 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
////////////////////////////////
|
||||
//~ Win32 Implementations
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
//- types
|
||||
|
||||
typedef int BOOL;
|
||||
typedef long LONG;
|
||||
typedef unsigned long ULONG;
|
||||
typedef unsigned __int64 ULONG_PTR, *PULONG_PTR;
|
||||
typedef unsigned long DWORD;
|
||||
typedef wchar_t WCHAR;
|
||||
typedef char const *LPCSTR;
|
||||
typedef const WCHAR *LPCWSTR, *PCWSTR;
|
||||
typedef LONG HRESULT;
|
||||
typedef void *HANDLE;
|
||||
struct HINSTANCE__;
|
||||
typedef struct HINSTANCE__ *HMODULE;
|
||||
typedef __int64 INT_PTR;
|
||||
typedef INT_PTR (*FARPROC)();
|
||||
|
||||
//- prototypes
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
__declspec(dllimport) HMODULE LoadLibraryA(LPCSTR name);
|
||||
__declspec(dllimport) FARPROC GetProcAddress(HMODULE module, LPCSTR name);
|
||||
__declspec(dllimport) BOOL FreeLibrary(HMODULE mod);
|
||||
__declspec(dllimport) HANDLE GetCurrentThread(void);
|
||||
__declspec(dllimport) DWORD GetCurrentThreadId(void);
|
||||
__declspec(dllimport) void RaiseException(DWORD dwExceptionCode, DWORD dwExceptionFlags, DWORD nNumberOfArguments, const ULONG_PTR *lpArguments);
|
||||
long long _InterlockedCompareExchange64(long long volatile*, long long, long long);
|
||||
long long _InterlockedExchangeAdd64(long long volatile*, long long);
|
||||
#pragma intrinsic(_InterlockedCompareExchange64)
|
||||
#pragma intrinsic(_InterlockedExchangeAdd64)
|
||||
int raddbg_markup_vsnprintf(char * const, unsigned long long const, const char * const, va_list);
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
//- helpers
|
||||
|
||||
typedef struct RADDBG_MARKUP_UnicodeDecode RADDBG_MARKUP_UnicodeDecode;
|
||||
struct RADDBG_MARKUP_UnicodeDecode
|
||||
{
|
||||
unsigned __int32 inc;
|
||||
unsigned __int32 codepoint;
|
||||
};
|
||||
static __int8 raddbg_utf8_class[32] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,2,2,2,2,3,3,4,5};
|
||||
|
||||
static inline RADDBG_MARKUP_UnicodeDecode
|
||||
raddbg_decode_utf8(char *str, unsigned __int64 max)
|
||||
{
|
||||
RADDBG_MARKUP_UnicodeDecode result = {1, 0xffffffff};
|
||||
unsigned __int8 byte = str[0];
|
||||
unsigned __int8 byte_class = raddbg_utf8_class[byte >> 3];
|
||||
switch(byte_class)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
result.codepoint = byte;
|
||||
}break;
|
||||
case 2:
|
||||
if(2 < max)
|
||||
{
|
||||
char cont_byte = str[1];
|
||||
if(raddbg_utf8_class[cont_byte >> 3] == 0)
|
||||
{
|
||||
result.codepoint = (byte & 0x0000001f) << 6;
|
||||
result.codepoint |= (cont_byte & 0x0000003f);
|
||||
result.inc = 2;
|
||||
}
|
||||
}break;
|
||||
case 3:
|
||||
if(2 < max)
|
||||
{
|
||||
char cont_byte[2] = {str[1], str[2]};
|
||||
if(raddbg_utf8_class[cont_byte[0] >> 3] == 0 &&
|
||||
raddbg_utf8_class[cont_byte[1] >> 3] == 0)
|
||||
{
|
||||
result.codepoint = (byte & 0x0000000f) << 12;
|
||||
result.codepoint |= ((cont_byte[0] & 0x0000003f) << 6);
|
||||
result.codepoint |= (cont_byte[1] & 0x0000003f);
|
||||
result.inc = 3;
|
||||
}
|
||||
}break;
|
||||
case 4:
|
||||
if(3 < max)
|
||||
{
|
||||
char cont_byte[3] = {str[1], str[2], str[3]};
|
||||
if(raddbg_utf8_class[cont_byte[0] >> 3] == 0 &&
|
||||
raddbg_utf8_class[cont_byte[1] >> 3] == 0 &&
|
||||
raddbg_utf8_class[cont_byte[2] >> 3] == 0)
|
||||
{
|
||||
result.codepoint = (byte & 0x00000007) << 18;
|
||||
result.codepoint |= ((cont_byte[0] & 0x0000003f) << 12);
|
||||
result.codepoint |= ((cont_byte[1] & 0x0000003f) << 6);
|
||||
result.codepoint |= (cont_byte[2] & 0x0000003f);
|
||||
result.inc = 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline unsigned __int32
|
||||
raddbg_encode_utf16(wchar_t *str, unsigned __int32 codepoint)
|
||||
{
|
||||
unsigned __int32 inc = 1;
|
||||
if(codepoint == 0xffffffff)
|
||||
{
|
||||
str[0] = (wchar_t)'?';
|
||||
}
|
||||
else if(codepoint < 0x10000)
|
||||
{
|
||||
str[0] = (wchar_t)codepoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
U32 v = codepoint - 0x10000;
|
||||
str[0] = (wchar_t)(0xD800 + (v >> 10));
|
||||
str[1] = (wchar_t)(0xDC00 + (v & 0x000003ff));
|
||||
inc = 2;
|
||||
}
|
||||
return inc;
|
||||
}
|
||||
|
||||
//- implementations
|
||||
|
||||
static inline int
|
||||
raddbg_is_attached__impl(void)
|
||||
{
|
||||
// TODO(rjf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
raddbg_thread_name__impl(char *fmt, ...)
|
||||
{
|
||||
// rjf: resolve variadic arguments
|
||||
char buffer[512] = {0};
|
||||
char *name = buffer;
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
raddbg_markup_vsnprintf(buffer, sizeof(buffer), fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
// rjf: get windows 10 style procedure
|
||||
HRESULT (*SetThreadDescription_function)(HANDLE hThread, PCWSTR lpThreadDescription) = 0;
|
||||
{
|
||||
static HRESULT (*global_SetThreadDescription_function)(HANDLE hThread, PCWSTR lpThreadDescription);
|
||||
static volatile __int64 global_SetThreadDescription_init_started;
|
||||
static volatile __int64 global_SetThreadDescription_init_done;
|
||||
__int64 do_init = !_InterlockedCompareExchange64(&global_SetThreadDescription_init_started, 1, 0);
|
||||
if(do_init)
|
||||
{
|
||||
HMODULE module = LoadLibraryA("kernel32.dll");
|
||||
global_SetThreadDescription_function = (HRESULT (*)(HANDLE, PCWSTR))GetProcAddress(module, "SetThreadDescription");
|
||||
FreeLibrary(module);
|
||||
_InterlockedExchangeAdd64(&global_SetThreadDescription_init_done, 1);
|
||||
}
|
||||
for(;_InterlockedExchangeAdd64(&global_SetThreadDescription_init_done, 0) == 0;)
|
||||
{
|
||||
// NOTE(rjf): busy-loop, until init is done
|
||||
}
|
||||
SetThreadDescription_function = global_SetThreadDescription_function;
|
||||
}
|
||||
|
||||
// rjf: set thread name, windows 10 style
|
||||
if(SetThreadDescription_function)
|
||||
{
|
||||
WCHAR buffer16[1024] = {0};
|
||||
int name_length = 0;
|
||||
for(;name[name_length]; name_length += 1);
|
||||
int write_offset = 0;
|
||||
for(int idx = 0; idx < name_length;)
|
||||
{
|
||||
RADDBG_MARKUP_UnicodeDecode decode = raddbg_decode_utf8(name+idx, name_length-idx);
|
||||
write_offset += raddbg_encode_utf16(buffer16 + write_offset, decode.codepoint);
|
||||
idx += decode.inc;
|
||||
}
|
||||
SetThreadDescription_function(GetCurrentThread(), buffer16);
|
||||
}
|
||||
|
||||
// rjf: set thread name, raise-exception style
|
||||
{
|
||||
#pragma pack(push, 8)
|
||||
typedef struct THREADNAME_INFO THREADNAME_INFO;
|
||||
struct THREADNAME_INFO
|
||||
{
|
||||
DWORD dwType;
|
||||
LPCSTR szName;
|
||||
DWORD dwThreadID;
|
||||
DWORD dwFlags;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
THREADNAME_INFO info;
|
||||
info.dwType = 0x1000;
|
||||
info.szName = name;
|
||||
info.dwThreadID = GetCurrentThreadId();
|
||||
info.dwFlags = 0;
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 6320 6322)
|
||||
__try
|
||||
{
|
||||
RaiseException(0x406D1388, 0, sizeof(info) / sizeof(void *), (const ULONG_PTR *)&info);
|
||||
}
|
||||
__except(1)
|
||||
{
|
||||
}
|
||||
#pragma warning(pop)
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
raddbg_thread_color__impl(unsigned int hexcode)
|
||||
{
|
||||
// TODO(rjf)
|
||||
}
|
||||
|
||||
#define raddbg_break__impl() (__debugbreak())
|
||||
|
||||
static inline void
|
||||
raddbg_watch__impl(char *fmt, ...)
|
||||
{
|
||||
// TODO(rjf)
|
||||
}
|
||||
|
||||
static inline void
|
||||
raddbg_log__impl(char *fmt, ...)
|
||||
{
|
||||
// TODO(rjf)
|
||||
}
|
||||
|
||||
#endif // defined(_WIN32)
|
||||
@@ -23,5 +23,255 @@
|
||||
#define raddbg_watch(fmt, ...) raddbg_watch__impl((fmt), __VA_ARGS__)
|
||||
#define raddbg_pin(expr, ...) /* NOTE(rjf): inspected by debugger ui - does not change program execution */
|
||||
#define raddbg_log(fmt, ...) raddbg_log__impl((fmt), __VA_ARGS__)
|
||||
#define raddbg_auto_view_rule(type, ...) raddbg_exe_data static char raddbg_auto_view_rule_data__##__COUNTER__[] = ("auto_view_rule: {type:" #type ", view_rule: " #__VA_ARGS__ "}")
|
||||
|
||||
////////////////////////////////
|
||||
//~ Win32 Implementations
|
||||
|
||||
#if defined(RADDBG_MARKUP_IMPLEMENTATION)
|
||||
#if defined(_WIN32)
|
||||
|
||||
//- section allocating
|
||||
#pragma section(".raddbg", read)
|
||||
#define raddbg_exe_data __declspec(allocate(".raddbg"))
|
||||
|
||||
//- types
|
||||
|
||||
typedef int BOOL;
|
||||
typedef long LONG;
|
||||
typedef unsigned long ULONG;
|
||||
typedef unsigned __int64 ULONG_PTR, *PULONG_PTR;
|
||||
typedef unsigned long DWORD;
|
||||
typedef wchar_t WCHAR;
|
||||
typedef char const *LPCSTR;
|
||||
typedef const WCHAR *LPCWSTR, *PCWSTR;
|
||||
typedef LONG HRESULT;
|
||||
typedef void *HANDLE;
|
||||
struct HINSTANCE__;
|
||||
typedef struct HINSTANCE__ *HMODULE;
|
||||
typedef __int64 INT_PTR;
|
||||
typedef INT_PTR (*FARPROC)();
|
||||
|
||||
//- prototypes
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
__declspec(dllimport) HMODULE LoadLibraryA(LPCSTR name);
|
||||
__declspec(dllimport) FARPROC GetProcAddress(HMODULE module, LPCSTR name);
|
||||
__declspec(dllimport) BOOL FreeLibrary(HMODULE mod);
|
||||
__declspec(dllimport) HANDLE GetCurrentThread(void);
|
||||
__declspec(dllimport) DWORD GetCurrentThreadId(void);
|
||||
__declspec(dllimport) void RaiseException(DWORD dwExceptionCode, DWORD dwExceptionFlags, DWORD nNumberOfArguments, const ULONG_PTR *lpArguments);
|
||||
long long _InterlockedCompareExchange64(long long volatile*, long long, long long);
|
||||
long long _InterlockedExchangeAdd64(long long volatile*, long long);
|
||||
#pragma intrinsic(_InterlockedCompareExchange64)
|
||||
#pragma intrinsic(_InterlockedExchangeAdd64)
|
||||
int raddbg_markup_vsnprintf(char * const, unsigned long long const, const char * const, va_list);
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
//- helpers
|
||||
|
||||
typedef struct RADDBG_MARKUP_UnicodeDecode RADDBG_MARKUP_UnicodeDecode;
|
||||
struct RADDBG_MARKUP_UnicodeDecode
|
||||
{
|
||||
unsigned __int32 inc;
|
||||
unsigned __int32 codepoint;
|
||||
};
|
||||
static __int8 raddbg_utf8_class[32] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,2,2,2,2,3,3,4,5};
|
||||
|
||||
static inline RADDBG_MARKUP_UnicodeDecode
|
||||
raddbg_decode_utf8(char *str, unsigned __int64 max)
|
||||
{
|
||||
RADDBG_MARKUP_UnicodeDecode result = {1, 0xffffffff};
|
||||
unsigned __int8 byte = str[0];
|
||||
unsigned __int8 byte_class = raddbg_utf8_class[byte >> 3];
|
||||
switch(byte_class)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
result.codepoint = byte;
|
||||
}break;
|
||||
case 2:
|
||||
if(2 < max)
|
||||
{
|
||||
char cont_byte = str[1];
|
||||
if(raddbg_utf8_class[cont_byte >> 3] == 0)
|
||||
{
|
||||
result.codepoint = (byte & 0x0000001f) << 6;
|
||||
result.codepoint |= (cont_byte & 0x0000003f);
|
||||
result.inc = 2;
|
||||
}
|
||||
}break;
|
||||
case 3:
|
||||
if(2 < max)
|
||||
{
|
||||
char cont_byte[2] = {str[1], str[2]};
|
||||
if(raddbg_utf8_class[cont_byte[0] >> 3] == 0 &&
|
||||
raddbg_utf8_class[cont_byte[1] >> 3] == 0)
|
||||
{
|
||||
result.codepoint = (byte & 0x0000000f) << 12;
|
||||
result.codepoint |= ((cont_byte[0] & 0x0000003f) << 6);
|
||||
result.codepoint |= (cont_byte[1] & 0x0000003f);
|
||||
result.inc = 3;
|
||||
}
|
||||
}break;
|
||||
case 4:
|
||||
if(3 < max)
|
||||
{
|
||||
char cont_byte[3] = {str[1], str[2], str[3]};
|
||||
if(raddbg_utf8_class[cont_byte[0] >> 3] == 0 &&
|
||||
raddbg_utf8_class[cont_byte[1] >> 3] == 0 &&
|
||||
raddbg_utf8_class[cont_byte[2] >> 3] == 0)
|
||||
{
|
||||
result.codepoint = (byte & 0x00000007) << 18;
|
||||
result.codepoint |= ((cont_byte[0] & 0x0000003f) << 12);
|
||||
result.codepoint |= ((cont_byte[1] & 0x0000003f) << 6);
|
||||
result.codepoint |= (cont_byte[2] & 0x0000003f);
|
||||
result.inc = 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline unsigned __int32
|
||||
raddbg_encode_utf16(wchar_t *str, unsigned __int32 codepoint)
|
||||
{
|
||||
unsigned __int32 inc = 1;
|
||||
if(codepoint == 0xffffffff)
|
||||
{
|
||||
str[0] = (wchar_t)'?';
|
||||
}
|
||||
else if(codepoint < 0x10000)
|
||||
{
|
||||
str[0] = (wchar_t)codepoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned __int32 v = codepoint - 0x10000;
|
||||
str[0] = (wchar_t)(0xD800 + (v >> 10));
|
||||
str[1] = (wchar_t)(0xDC00 + (v & 0x000003ff));
|
||||
inc = 2;
|
||||
}
|
||||
return inc;
|
||||
}
|
||||
|
||||
//- implementations
|
||||
|
||||
static inline int
|
||||
raddbg_is_attached__impl(void)
|
||||
{
|
||||
// TODO(rjf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
raddbg_thread_name__impl(char *fmt, ...)
|
||||
{
|
||||
// rjf: resolve variadic arguments
|
||||
char buffer[512] = {0};
|
||||
char *name = buffer;
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
raddbg_markup_vsnprintf(buffer, sizeof(buffer), fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
// rjf: get windows 10 style procedure
|
||||
HRESULT (*SetThreadDescription_function)(HANDLE hThread, PCWSTR lpThreadDescription) = 0;
|
||||
{
|
||||
static HRESULT (*global_SetThreadDescription_function)(HANDLE hThread, PCWSTR lpThreadDescription);
|
||||
static volatile __int64 global_SetThreadDescription_init_started;
|
||||
static volatile __int64 global_SetThreadDescription_init_done;
|
||||
__int64 do_init = !_InterlockedCompareExchange64(&global_SetThreadDescription_init_started, 1, 0);
|
||||
if(do_init)
|
||||
{
|
||||
HMODULE module = LoadLibraryA("kernel32.dll");
|
||||
global_SetThreadDescription_function = (HRESULT (*)(HANDLE, PCWSTR))GetProcAddress(module, "SetThreadDescription");
|
||||
FreeLibrary(module);
|
||||
_InterlockedExchangeAdd64(&global_SetThreadDescription_init_done, 1);
|
||||
}
|
||||
for(;_InterlockedExchangeAdd64(&global_SetThreadDescription_init_done, 0) == 0;)
|
||||
{
|
||||
// NOTE(rjf): busy-loop, until init is done
|
||||
}
|
||||
SetThreadDescription_function = global_SetThreadDescription_function;
|
||||
}
|
||||
|
||||
// rjf: set thread name, windows 10 style
|
||||
if(SetThreadDescription_function)
|
||||
{
|
||||
WCHAR buffer16[1024] = {0};
|
||||
int name_length = 0;
|
||||
for(;name[name_length]; name_length += 1);
|
||||
int write_offset = 0;
|
||||
for(int idx = 0; idx < name_length;)
|
||||
{
|
||||
RADDBG_MARKUP_UnicodeDecode decode = raddbg_decode_utf8(name+idx, name_length-idx);
|
||||
write_offset += raddbg_encode_utf16(buffer16 + write_offset, decode.codepoint);
|
||||
idx += decode.inc;
|
||||
}
|
||||
SetThreadDescription_function(GetCurrentThread(), buffer16);
|
||||
}
|
||||
|
||||
// rjf: set thread name, raise-exception style
|
||||
{
|
||||
#pragma pack(push, 8)
|
||||
typedef struct THREADNAME_INFO THREADNAME_INFO;
|
||||
struct THREADNAME_INFO
|
||||
{
|
||||
DWORD dwType;
|
||||
LPCSTR szName;
|
||||
DWORD dwThreadID;
|
||||
DWORD dwFlags;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
THREADNAME_INFO info;
|
||||
info.dwType = 0x1000;
|
||||
info.szName = name;
|
||||
info.dwThreadID = GetCurrentThreadId();
|
||||
info.dwFlags = 0;
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 6320 6322)
|
||||
__try
|
||||
{
|
||||
RaiseException(0x406D1388, 0, sizeof(info) / sizeof(void *), (const ULONG_PTR *)&info);
|
||||
}
|
||||
__except(1)
|
||||
{
|
||||
}
|
||||
#pragma warning(pop)
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
raddbg_thread_color__impl(unsigned int hexcode)
|
||||
{
|
||||
// TODO(rjf)
|
||||
}
|
||||
|
||||
#define raddbg_break__impl() (__debugbreak())
|
||||
|
||||
static inline void
|
||||
raddbg_watch__impl(char *fmt, ...)
|
||||
{
|
||||
// TODO(rjf)
|
||||
}
|
||||
|
||||
static inline void
|
||||
raddbg_log__impl(char *fmt, ...)
|
||||
{
|
||||
// TODO(rjf)
|
||||
}
|
||||
|
||||
#endif // defined(_WIN32)
|
||||
#endif // defined(RADDBG_MARKUP_IMPLEMENTATION)
|
||||
|
||||
#endif // RADDBG_MARKUP_H
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
** stepping, breakpoints, evaluation, cross-module calls.
|
||||
*/
|
||||
|
||||
#define RADDBG_MARKUP_IMPLEMENTATION
|
||||
#include "lib_raddbg_markup/raddbg_markup.h"
|
||||
|
||||
////////////////////////////////
|
||||
@@ -142,6 +143,7 @@ struct Fixed_Array{
|
||||
int count;
|
||||
};
|
||||
|
||||
raddbg_auto_view_rule(Dynamic?, slice);
|
||||
struct Dynamic_Array{
|
||||
Pair *pairs;
|
||||
int count;
|
||||
|
||||
@@ -13900,15 +13900,39 @@ rd_frame(void)
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: gather auto-view-rules from loaded modules
|
||||
RD_CfgList immediate_auto_view_rules = {0};
|
||||
CTRL_EntityList modules = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Module);
|
||||
for(CTRL_EntityNode *n = modules.first; n != 0; n = n->next)
|
||||
{
|
||||
String8 raddbg_data = ctrl_raddbg_data_from_module(scratch.arena, n->v->handle);
|
||||
RD_CfgList cfgs = rd_cfg_tree_list_from_string(scratch.arena, raddbg_data);
|
||||
RD_Cfg *immediate_root = rd_immediate_cfg_from_keyf("module_%S_cfgs", ctrl_string_from_handle(scratch.arena, n->v->handle));
|
||||
for(RD_CfgNode *n = cfgs.first; n != 0; n = n->next)
|
||||
{
|
||||
rd_cfg_insert_child(immediate_root, immediate_root->last, n->v);
|
||||
rd_cfg_list_push(scratch.arena, &immediate_auto_view_rules, n->v);
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: add auto-hook rules for auto-view-rules
|
||||
{
|
||||
RD_CfgList auto_view_rules = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("auto_view_rule"));
|
||||
for(RD_CfgNode *n = auto_view_rules.first; n != 0; n = n->next)
|
||||
RD_CfgList rules_lists[] =
|
||||
{
|
||||
RD_Cfg *rule = n->v;
|
||||
String8 type_string = rd_cfg_child_from_string(rule, str8_lit("type"))->first->string;
|
||||
String8 view_rule_string = rd_cfg_child_from_string(rule, str8_lit("view_rule"))->first->string;
|
||||
e_auto_hook_map_insert_new(scratch.arena, ctx->auto_hook_map, .type_pattern = type_string, .tag_expr_string = view_rule_string);
|
||||
auto_view_rules,
|
||||
immediate_auto_view_rules,
|
||||
};
|
||||
for EachElement(list_idx, rules_lists)
|
||||
{
|
||||
RD_CfgList list = rules_lists[list_idx];
|
||||
for(RD_CfgNode *n = list.first; n != 0; n = n->next)
|
||||
{
|
||||
RD_Cfg *rule = n->v;
|
||||
String8 type_string = rd_cfg_child_from_string(rule, str8_lit("type"))->first->string;
|
||||
String8 view_rule_string = rd_cfg_child_from_string(rule, str8_lit("view_rule"))->first->string;
|
||||
e_auto_hook_map_insert_new(scratch.arena, ctx->auto_hook_map, .type_pattern = type_string, .tag_expr_string = view_rule_string);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -388,7 +388,6 @@
|
||||
#include "third_party/rad_lzb_simple/rad_lzb_simple.h"
|
||||
#include "third_party/rad_lzb_simple/rad_lzb_simple.c"
|
||||
#include "lib_raddbg_markup/raddbg_markup.h"
|
||||
#include "lib_raddbg_markup/raddbg_markup.c"
|
||||
|
||||
//- rjf: [h]
|
||||
#include "base/base_inc.h"
|
||||
|
||||
Reference in New Issue
Block a user