Thread ID lookup and naming.

This commit is contained in:
Ben Vanik 2014-01-07 20:54:47 -08:00
parent 20b76b0e59
commit 5fd0b211ce
5 changed files with 94 additions and 0 deletions

View File

@ -82,3 +82,31 @@ void KernelState::SetExecutableModule(XModule* module) {
executable_module_->Retain(); executable_module_->Retain();
} }
} }
void KernelState::RegisterThread(XThread* thread) {
xe_mutex_lock(object_mutex_);
threads_by_id_[thread->thread_id()] = thread;
xe_mutex_unlock(object_mutex_);
}
void KernelState::UnregisterThread(XThread* thread) {
xe_mutex_lock(object_mutex_);
auto it = threads_by_id_.find(thread->thread_id());
if (it != threads_by_id_.end()) {
threads_by_id_.erase(it);
}
xe_mutex_unlock(object_mutex_);
}
XThread* KernelState::GetThreadByID(uint32_t thread_id) {
XThread* thread = NULL;
xe_mutex_lock(object_mutex_);
auto it = threads_by_id_.find(thread_id);
if (it != threads_by_id_.end()) {
thread = it->second;
// Caller must release.
thread->Retain();
}
xe_mutex_unlock(object_mutex_);
return thread;
}

View File

@ -22,6 +22,7 @@
XEDECLARECLASS2(xe, cpu, Processor); XEDECLARECLASS2(xe, cpu, Processor);
XEDECLARECLASS2(xe, kernel, XModule); XEDECLARECLASS2(xe, kernel, XModule);
XEDECLARECLASS2(xe, kernel, XThread);
XEDECLARECLASS3(xe, kernel, fs, FileSystem); XEDECLARECLASS3(xe, kernel, fs, FileSystem);
@ -47,6 +48,10 @@ public:
XModule* GetExecutableModule(); XModule* GetExecutableModule();
void SetExecutableModule(XModule* module); void SetExecutableModule(XModule* module);
void RegisterThread(XThread* thread);
void UnregisterThread(XThread* thread);
XThread* GetThreadByID(uint32_t thread_id);
private: private:
Emulator* emulator_; Emulator* emulator_;
Memory* memory_; Memory* memory_;
@ -55,6 +60,7 @@ private:
ObjectTable* object_table_; ObjectTable* object_table_;
xe_mutex_t* object_mutex_; xe_mutex_t* object_mutex_;
std::unordered_map<uint32_t, XThread*> threads_by_id_;
XModule* executable_module_; XModule* executable_module_;

View File

@ -40,6 +40,7 @@ XThread::XThread(KernelState* kernel_state,
thread_state_address_(0), thread_state_address_(0),
thread_state_(0), thread_state_(0),
event_(NULL), event_(NULL),
name_(0),
irql_(0) { irql_(0) {
creation_params_.stack_size = stack_size; creation_params_.stack_size = stack_size;
creation_params_.xapi_thread_startup = xapi_thread_startup; creation_params_.xapi_thread_startup = xapi_thread_startup;
@ -54,9 +55,15 @@ XThread::XThread(KernelState* kernel_state,
event_ = new XEvent(kernel_state); event_ = new XEvent(kernel_state);
event_->Initialize(true, false); event_->Initialize(true, false);
// The kernel does not take a reference. We must unregister in the dtor.
kernel_state_->RegisterThread(this);
} }
XThread::~XThread() { XThread::~XThread() {
// Unregister first to prevent lookups while deleting.
kernel_state_->UnregisterThread(this);
event_->Release(); event_->Release();
PlatformDestroy(); PlatformDestroy();
@ -70,6 +77,9 @@ XThread::~XThread() {
if (thread_state_address_) { if (thread_state_address_) {
kernel_state()->memory()->HeapFree(thread_state_address_, 0); kernel_state()->memory()->HeapFree(thread_state_address_, 0);
} }
if (name_) {
xe_free(name_);
}
if (thread_handle_) { if (thread_handle_) {
// TODO(benvanik): platform kill // TODO(benvanik): platform kill
@ -121,6 +131,37 @@ void XThread::set_last_error(uint32_t error_code) {
XESETUINT32BE(p + 0x160, error_code); XESETUINT32BE(p + 0x160, error_code);
} }
void XThread::set_name(const char* name) {
if (name == name_) {
return;
}
if (name_) {
xe_free(name_);
}
name_ = xestrdupa(name);
#if XE_PLATFORM(WIN32)
// Do the nasty set for us.
#pragma pack(push, 8)
typedef struct tagTHREADNAME_INFO {
DWORD dwType; // must be 0x1000
LPCSTR szName; // pointer to name (in user addr space)
DWORD dwThreadID; // thread ID (-1=caller thread)
DWORD dwFlags; // reserved for future use, must be zero
} THREADNAME_INFO;
#pragma pack(pop)
THREADNAME_INFO info;
info.dwType = 0x1000;
info.szName = name_;
info.dwThreadID = ::GetThreadId(thread_handle_);
info.dwFlags = 0;
__try {
RaiseException(0x406D1388, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info);
} __except(EXCEPTION_CONTINUE_EXECUTION) {
}
#endif // WIN32
}
X_STATUS XThread::Create() { X_STATUS XThread::Create() {
// Allocate thread state block from heap. // Allocate thread state block from heap.
// This is set as r13 for user code and some special inlined Win32 calls // This is set as r13 for user code and some special inlined Win32 calls

View File

@ -46,6 +46,8 @@ public:
uint32_t thread_id(); uint32_t thread_id();
uint32_t last_error(); uint32_t last_error();
void set_last_error(uint32_t error_code); void set_last_error(uint32_t error_code);
const char* name() const { return name_; }
void set_name(const char* name);
X_STATUS Create(); X_STATUS Create();
X_STATUS Exit(int exit_code); X_STATUS Exit(int exit_code);
@ -83,6 +85,8 @@ private:
uint32_t thread_state_address_; uint32_t thread_state_address_;
cpu::XenonThreadState* thread_state_; cpu::XenonThreadState* thread_state_;
char* name_;
uint32_t irql_; uint32_t irql_;
XEvent* event_; XEvent* event_;

View File

@ -241,6 +241,20 @@ SHIM_CALL DbgBreakPoint_shim(
} }
SHIM_CALL RtlRaiseException_shim(
PPCContext* ppc_state, KernelState* state) {
uint32_t record_ptr = SHIM_GET_ARG_32(0);
uint32_t code = SHIM_MEM_32(record_ptr + 0);
XELOGD(
"RtlRaiseException(%.8X(%.8X))",
record_ptr, code);
XEASSERTALWAYS();
}
} // namespace kernel } // namespace kernel
} // namespace xe } // namespace xe
@ -249,4 +263,5 @@ void xe::kernel::xboxkrnl::RegisterDebugExports(
ExportResolver* export_resolver, KernelState* state) { ExportResolver* export_resolver, KernelState* state) {
SHIM_SET_MAPPING("xboxkrnl.exe", DbgPrint, state); SHIM_SET_MAPPING("xboxkrnl.exe", DbgPrint, state);
SHIM_SET_MAPPING("xboxkrnl.exe", DbgBreakPoint, state); SHIM_SET_MAPPING("xboxkrnl.exe", DbgBreakPoint, state);
SHIM_SET_MAPPING("xboxkrnl.exe", RtlRaiseException, state);
} }