summaryrefslogtreecommitdiff
path: root/src/debug/daccess/reimpl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/debug/daccess/reimpl.cpp')
-rw-r--r--src/debug/daccess/reimpl.cpp115
1 files changed, 115 insertions, 0 deletions
diff --git a/src/debug/daccess/reimpl.cpp b/src/debug/daccess/reimpl.cpp
new file mode 100644
index 0000000000..d1198eea7b
--- /dev/null
+++ b/src/debug/daccess/reimpl.cpp
@@ -0,0 +1,115 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+//*****************************************************************************
+// File: reimpl.cpp
+//
+
+//
+// Data-access-specific reimplementations of standard code.
+//
+//*****************************************************************************
+
+#include "stdafx.h"
+
+//
+// Get the Thread instance for a specific OS thread ID
+//
+// Arguments:
+// osThread - the OS thread ID of interest.
+//
+// Return value:
+// A Thread object marshalled from the target corresponding to the specified OS thread
+// ID, or NULL if there is no such Thread.
+//
+// Notes:
+// We used to accept a thread ID of '0' to mean "use the current thread", which was based on
+// ICLRDataTarget::GetCurrentThreadID. But this is error-prone and not well-defined (many data targets
+// don't implement that API). It's better to require explicit thread IDs to be passed down when they
+// are needed.
+//
+Thread* __stdcall
+DacGetThread(ULONG32 osThread)
+{
+ _ASSERTE(osThread > 0);
+
+ if (!g_dacImpl)
+ {
+ DacError(E_UNEXPECTED);
+ UNREACHABLE();
+ }
+
+ // Note that if we had access to TLS, we could get this at index gThreadTLSIndex for the specified
+ // thread. However, this is the only place we might want to use TLS, and it's not performance critical,
+ // so we haven't added TLS support to ICorDebugDataTarget (the legacy ICLRDataTarget interface has it though)
+
+ // Scan the whole thread store to see if there's a matching thread.
+
+ if (!ThreadStore::s_pThreadStore)
+ {
+ return NULL;
+ }
+
+ Thread* thread = ThreadStore::s_pThreadStore->m_ThreadList.GetHead();
+ while (thread)
+ {
+ if (thread->GetOSThreadId() == osThread)
+ {
+ return thread;
+ }
+
+ thread = ThreadStore::s_pThreadStore->m_ThreadList.GetNext(thread);
+ }
+
+ return NULL;
+}
+
+EXTERN_C Thread* GetThread()
+{
+ // In dac mode it's unlikely that the thread calling dac
+ // is actually the same "current thread" that the runtime cares
+ // about. Fail all queries of the current thread by
+ // the runtime code to catch any inadvertent usage.
+ // Enumerating the ThreadStore is the proper way to get access
+ // to specific Thread objects.
+ DacError(E_UNEXPECTED);
+ return NULL;
+}
+
+BOOL
+DacGetThreadContext(Thread* thread, T_CONTEXT* context)
+{
+ SUPPORTS_DAC;
+
+ if (!g_dacImpl)
+ {
+ DacError(E_UNEXPECTED);
+ UNREACHABLE();
+ }
+
+ // XXX Microsoft - How do you retrieve the context for
+ // a Thread that's not running?
+ if (!thread->GetOSThreadId() ||
+ thread->GetOSThreadId() == 0xbaadf00d)
+ {
+ DacError(E_UNEXPECTED);
+ UNREACHABLE();
+ }
+
+ ULONG32 contextFlags;
+
+ contextFlags = CONTEXT_ALL;
+
+ HRESULT status =
+ g_dacImpl->m_pTarget->
+ GetThreadContext(thread->GetOSThreadId(), contextFlags,
+ sizeof(*context), (PBYTE)context);
+ if (status != S_OK)
+ {
+ DacError(status);
+ UNREACHABLE();
+ }
+
+ return TRUE;
+}
+