diff --git a/src/ctrl/ctrl.mdesk b/src/ctrl/ctrl.mdesk index 5665654d..ceb2fca1 100644 --- a/src/ctrl/ctrl.mdesk +++ b/src/ctrl/ctrl.mdesk @@ -14,8 +14,9 @@ CTRL_EntityKindTable: {Module module "Module" } {EntryPoint entry_point "Entry Point" } {DebugInfoPath debug_info_path "Debug Info Path" } - {PendingThreadName pending_thread_name "Pending Thread Name" } - {Breakpoint breakpoint "Breakpoint" } + {PendingThreadName pending_thread_name "Pending Thread Name" } + {PendingThreadColor pending_thread_color "Pending Thread Color" } + {Breakpoint breakpoint "Breakpoint" } } @enum CTRL_EntityKind: diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index c5fce76f..1b9a4c48 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -1023,6 +1023,21 @@ ctrl_process_from_entity(CTRL_Entity *entity) return result; } +internal CTRL_Entity * +ctrl_thread_from_id(CTRL_EntityStore *store, U64 id) +{ + CTRL_Entity *thread = &ctrl_entity_nil; + CTRL_EntityArray threads = ctrl_entity_array_from_kind(store, CTRL_EntityKind_Thread); + for EachIndex(idx, threads.count) + { + if(threads.v[idx]->id == id) + { + thread = threads.v[idx]; + } + } + return thread; +} + internal CTRL_Entity * ctrl_module_from_process_vaddr(CTRL_Entity *process, U64 vaddr) { @@ -1239,6 +1254,17 @@ ctrl_entity_store_apply_events(CTRL_EntityStore *store, CTRL_EventList *list) break; } } + CTRL_EntityArray pending_thread_colors = ctrl_entity_array_from_kind(store, CTRL_EntityKind_PendingThreadColor); + for EachIndex(idx, pending_thread_colors.count) + { + CTRL_Entity *entity = pending_thread_colors.v[idx]; + if(entity->id == event->entity_id) + { + thread->rgba = entity->rgba; + ctrl_entity_release(store, entity); + break; + } + } thread->stack_base = event->stack_base; ctrl_query_cached_rip_from_thread(store, event->entity); }break; @@ -1250,21 +1276,46 @@ ctrl_entity_store_apply_events(CTRL_EntityStore *store, CTRL_EventList *list) case CTRL_EventKind_ThreadName: { CTRL_Entity *process = ctrl_entity_from_handle(store, event->parent); - CTRL_Entity *thread = ctrl_entity_from_handle(store, event->entity); - if(event->entity_id != 0) + CTRL_Entity *thread = &ctrl_entity_nil; + if(event->entity_id == 0) + { + thread = ctrl_entity_from_handle(store, event->entity); + } + else + { + thread = ctrl_thread_from_id(store, event->entity_id); + } + if(thread != &ctrl_entity_nil) + { + ctrl_entity_equip_string(store, thread, event->string); + } + else { CTRL_Entity *pending_name = ctrl_entity_alloc(store, process, CTRL_EntityKind_PendingThreadName, Arch_Null, ctrl_handle_zero(), event->entity_id); ctrl_entity_equip_string(store, pending_name, event->string); } - else if(thread != &ctrl_entity_nil) - { - ctrl_entity_equip_string(store, thread, event->string); - } }break; case CTRL_EventKind_ThreadColor: { - CTRL_Entity *thread = ctrl_entity_from_handle(store, event->entity); - thread->rgba = event->rgba; + CTRL_Entity *process = ctrl_entity_from_handle(store, event->parent); + CTRL_Entity *thread = &ctrl_entity_nil; + if(event->entity_id == 0) + { + thread = ctrl_entity_from_handle(store, event->entity); + } + else + { + thread = ctrl_thread_from_id(store, event->entity_id); + } + if(thread != &ctrl_entity_nil) + { + thread->rgba = event->rgba; + } + else + { + CTRL_Entity *pending = ctrl_entity_alloc(store, process, CTRL_EntityKind_PendingThreadColor, Arch_Null, ctrl_handle_zero(), event->entity_id); + pending->rgba = event->rgba; + } }break; case CTRL_EventKind_ThreadFrozen: { @@ -4399,7 +4450,8 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, out_evt->msg_id = msg->msg_id; out_evt->entity = ctrl_handle_make(CTRL_MachineID_Local, event->thread); out_evt->parent = ctrl_handle_make(CTRL_MachineID_Local, event->process); - out_evt->rgba = event->code; + out_evt->entity_id = event->code; + out_evt->rgba = event->user_data; }break; case DMN_EventKind_SetBreakpoint: { diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index 73f6b2c2..86edf6c3 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -843,6 +843,7 @@ internal CTRL_Entity *ctrl_entity_from_handle(CTRL_EntityStore *store, CTRL_Hand internal CTRL_Entity *ctrl_entity_child_from_kind(CTRL_Entity *parent, CTRL_EntityKind kind); internal CTRL_Entity *ctrl_entity_ancestor_from_kind(CTRL_Entity *entity, CTRL_EntityKind kind); internal CTRL_Entity *ctrl_process_from_entity(CTRL_Entity *entity); +internal CTRL_Entity *ctrl_thread_from_id(CTRL_EntityStore *store, U64 id); internal CTRL_Entity *ctrl_module_from_process_vaddr(CTRL_Entity *process, U64 vaddr); internal DI_Key ctrl_dbgi_key_from_module(CTRL_Entity *module); internal CTRL_EntityList ctrl_modules_from_dbgi_key(Arena *arena, CTRL_EntityStore *store, DI_Key *dbgi_key); diff --git a/src/ctrl/generated/ctrl.meta.c b/src/ctrl/generated/ctrl.meta.c index 87ed9c81..c7d5dd88 100644 --- a/src/ctrl/generated/ctrl.meta.c +++ b/src/ctrl/generated/ctrl.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -String8 ctrl_entity_kind_code_name_table[10] = +String8 ctrl_entity_kind_code_name_table[11] = { {0}, str8_lit_comp("root"), @@ -15,10 +15,11 @@ str8_lit_comp("module"), str8_lit_comp("entry_point"), str8_lit_comp("debug_info_path"), str8_lit_comp("pending_thread_name"), +str8_lit_comp("pending_thread_color"), str8_lit_comp("breakpoint"), }; -String8 ctrl_entity_kind_display_string_table[10] = +String8 ctrl_entity_kind_display_string_table[11] = { {0}, str8_lit_comp("Root"), @@ -29,6 +30,7 @@ str8_lit_comp("Module"), str8_lit_comp("EntryPoint"), str8_lit_comp("DebugInfoPath"), str8_lit_comp("PendingThreadName"), +str8_lit_comp("PendingThreadColor"), str8_lit_comp("Breakpoint"), }; diff --git a/src/ctrl/generated/ctrl.meta.h b/src/ctrl/generated/ctrl.meta.h index 14dfc6a8..56f7b8db 100644 --- a/src/ctrl/generated/ctrl.meta.h +++ b/src/ctrl/generated/ctrl.meta.h @@ -17,6 +17,7 @@ CTRL_EntityKind_Module, CTRL_EntityKind_EntryPoint, CTRL_EntityKind_DebugInfoPath, CTRL_EntityKind_PendingThreadName, +CTRL_EntityKind_PendingThreadColor, CTRL_EntityKind_Breakpoint, CTRL_EntityKind_COUNT, } CTRL_EntityKind; @@ -65,8 +66,8 @@ CTRL_ExceptionCodeKind_COUNT, } CTRL_ExceptionCodeKind; C_LINKAGE_BEGIN -extern String8 ctrl_entity_kind_code_name_table[10]; -extern String8 ctrl_entity_kind_display_string_table[10]; +extern String8 ctrl_entity_kind_code_name_table[11]; +extern String8 ctrl_entity_kind_display_string_table[11]; extern U32 ctrl_exception_code_kind_code_table[38]; extern String8 ctrl_exception_code_kind_display_string_table[38]; extern String8 ctrl_exception_code_kind_lowercase_code_string_table[38]; diff --git a/src/demon/win32/demon_core_win32.c b/src/demon/win32/demon_core_win32.c index 6480d200..bd6bfb6f 100644 --- a/src/demon/win32/demon_core_win32.c +++ b/src/demon/win32/demon_core_win32.c @@ -2524,7 +2524,8 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) case DMN_W32_EXCEPTION_RADDBG_SET_THREAD_COLOR: { e->kind = DMN_EventKind_SetThreadColor; - e->code = exception->ExceptionInformation[1]; + e->code = exception->ExceptionInformation[0]; + e->user_data = exception->ExceptionInformation[1]; }break; //- rjf: fill set-data-breakpoint info diff --git a/src/lib_raddbg_markup/raddbg_markup.h b/src/lib_raddbg_markup/raddbg_markup.h index 4b186079..9e639a4d 100644 --- a/src/lib_raddbg_markup/raddbg_markup.h +++ b/src/lib_raddbg_markup/raddbg_markup.h @@ -19,25 +19,15 @@ //////////////////////////////// //~ Usage Macros -#if defined(RADDBG_MARKUP_STUBS) -# define raddbg_is_attached(...) (0) -# define raddbg_thread_name(fmt, ...) ((void)0) -# define raddbg_thread_color_hex(hexcode) ((void)0) -# define raddbg_thread_color_rgba(r, g, b, a) ((void)0) -# define raddbg_break(...) ((void)0) -# define raddbg_break_if(expr, ...) ((void)expr) -# define raddbg_watch(fmt, ...) ((void)0) -# define raddbg_pin(expr, ...) -# define raddbg_log(fmt, ...) ((void)0) -# define raddbg_entry_point(...) struct raddbg_gen_data_id(){int __unused__} -# define raddbg_type_view(type, ...) struct raddbg_gen_data_id(){int __unused__} -# define raddbg_add_breakpoint(ptr, size, r, w, x) ((void)0) -# define raddbg_remove_breakpoint(ptr, size, r, w, x) ((void)0) -#else +#if !defined(RADDBG_MARKUP_STUBS) # define raddbg_is_attached(...) raddbg_is_attached__impl() -# define raddbg_thread_name(fmt, ...) raddbg_thread_name__impl((fmt), __VA_ARGS__) -# define raddbg_thread_color_hex(hexcode) raddbg_thread_color__impl((hexcode)) -# define raddbg_thread_color_rgba(r, g, b, a) raddbg_thread_color__impl(((unsigned int)((r)*255) << 24) | ((unsigned int)((g)*255) << 16) | ((unsigned int)((b)*255) << 8) | ((unsigned int)(a)*255)) +# define raddbg_thread_id(...) raddbg_thread_id__impl() +# define raddbg_thread_name(fmt, ...) raddbg_thread_name__impl(raddbg_thread_id(), (fmt), __VA_ARGS__) +# define raddbg_thread_id_name(id, fmt, ...) raddbg_thread_name__impl((id), (fmt), __VA_ARGS__) +# define raddbg_thread_color_u32(u32) raddbg_thread_color__impl(raddbg_thread_id(), (u32)) +# define raddbg_thread_color_rgba(r, g, b, a) raddbg_thread_color__impl(raddbg_thread_id(), ((unsigned int)((r)*255) << 24) | ((unsigned int)((g)*255) << 16) | ((unsigned int)((b)*255) << 8) | ((unsigned int)(a)*255)) +# define raddbg_thread_id_color_u32(id, u32) raddbg_thread_color__impl((id), (u32)) +# define raddbg_thread_id_color_rgba(id, r, g, b, a) raddbg_thread_color__impl((id), ((unsigned int)((r)*255) << 24) | ((unsigned int)((g)*255) << 16) | ((unsigned int)((b)*255) << 8) | ((unsigned int)(a)*255)) # define raddbg_break(...) raddbg_break__impl() # define raddbg_break_if(expr, ...) ((expr) ? raddbg_break__impl() : (void)0) # define raddbg_watch(fmt, ...) raddbg_watch__impl((fmt), __VA_ARGS__) @@ -47,6 +37,24 @@ # define raddbg_type_view(type, ...) raddbg_exe_data static char raddbg_gen_data_id()[] = ("type_view: {type: \"" #type "\", expr: \"" #__VA_ARGS__ "\"}") # define raddbg_add_breakpoint(ptr, size, r, w, x) raddbg_add_or_remove_breakpoint__impl((ptr), (1), (size), (r), (w), (x)) # define raddbg_remove_breakpoint(ptr, size, r, w, x) raddbg_add_or_remove_breakpoint__impl((ptr), (0), (size), (r), (w), (x)) +#else +# define raddbg_is_attached(...) (0) +# define raddbg_thread_id(...) ((void)0) +# define raddbg_thread_name(fmt, ...) ((void)0) +# define raddbg_thread_id_name(id, fmt, ...) ((void)0) +# define raddbg_thread_color_u32(u32) ((void)0) +# define raddbg_thread_color_rgba(r, g, b, a) ((void)0) +# define raddbg_thread_id_color_u32(id, u32) ((void)0) +# define raddbg_thread_id_color_rgba(id, r, g, b, a) ((void)0) +# define raddbg_break(...) ((void)0) +# define raddbg_break_if(expr, ...) ((void)expr) +# define raddbg_watch(fmt, ...) ((void)0) +# define raddbg_pin(expr, ...) +# define raddbg_log(fmt, ...) ((void)0) +# define raddbg_entry_point(...) struct raddbg_gen_data_id(){int __unused__} +# define raddbg_type_view(type, ...) struct raddbg_gen_data_id(){int __unused__} +# define raddbg_add_breakpoint(ptr, size, r, w, x) ((void)0) +# define raddbg_remove_breakpoint(ptr, size, r, w, x) ((void)0) #endif //////////////////////////////// @@ -212,8 +220,15 @@ raddbg_is_attached__impl(void) return !!raddbg_is_attached_byte_marker[0]; } +static inline int +raddbg_thread_id__impl(void) +{ + DWORD result = GetCurrentThreadId(); + return result; +} + static inline void -raddbg_thread_name__impl(char *fmt, ...) +raddbg_thread_name__impl(int id, char *fmt, ...) { // rjf: resolve variadic arguments char buffer[512] = {0}; @@ -247,7 +262,7 @@ raddbg_thread_name__impl(char *fmt, ...) } // rjf: set thread name, windows 10 style - if(SetThreadDescription_function) + if(SetThreadDescription_function && id == GetCurrentThreadId()) { WCHAR buffer16[1024] = {0}; int name_length = 0; @@ -277,7 +292,7 @@ raddbg_thread_name__impl(char *fmt, ...) THREADNAME_INFO info; info.dwType = 0x1000; info.szName = name; - info.dwThreadID = GetCurrentThreadId(); + info.dwThreadID = id; info.dwFlags = 0; #pragma warning(push) #pragma warning(disable: 6320 6322) @@ -293,7 +308,7 @@ raddbg_thread_name__impl(char *fmt, ...) } static inline void -raddbg_thread_color__impl(unsigned int hexcode) +raddbg_thread_color__impl(int id, unsigned int hexcode) { if(raddbg_is_attached()) { @@ -302,13 +317,13 @@ raddbg_thread_color__impl(unsigned int hexcode) struct RADDBG_ThreadColorInfo { DWORD dwThreadID; - DWORD _pad0_; + DWORD _pad_0; DWORD rgba; - DWORD _pad1_; + DWORD _pad_1; }; #pragma pack(pop) RADDBG_ThreadColorInfo info; - info.dwThreadID = GetCurrentThreadId(); + info.dwThreadID = id; info.rgba = hexcode; #pragma warning(push) #pragma warning(disable: 6320 6322) diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index 645ee7cc..d5b43817 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -2597,30 +2597,8 @@ thread_name_tests(void) #if _WIN32 DWORD id = 0; HANDLE h = CreateThread(0, 0, dummy_thread, 0, CREATE_SUSPENDED, &id); - { -#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 = "dummy_thread"; - info.dwThreadID = id; - info.dwFlags = 0; - __try - { - RaiseException(0x406D1388, 0, sizeof(info) / sizeof(void *), (const ULONG_PTR *)&info); - } - __except(1) - { - } - } + raddbg_thread_id_name(id, "dummy_thread"); + raddbg_thread_id_color_u32(id, 0xff1f23ff); ResumeThread(h); WaitForSingleObject(h, INFINITE); #endif diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 8f00f15e..2a289b3b 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -164,8 +164,8 @@ // - `raddbg_log(format, ...)`, e.g. // `raddbg_log("This is a number: %i", 123)`: Writes a debug string for a // debugger to read and display in its UI. -// - `raddbg_thread_color_hex(hexcode)`, e.g. -// `raddbg_thread_color_hex(0xff0000ff)`: Sets the calling thread's color. +// - `raddbg_thread_color_u32(hexcode)`, e.g. +// `raddbg_thread_color_u32(0xff0000ff)`: Sets the calling thread's color. // - Also can be done with individual `[0, 1]` color components: // `raddbg_thread_color_rgba(1.f, 0.f, 0.f, 1.f)` // - `raddbg_pin()`, e.g.