blob: d1198eea7b891e5d2179eff51d7bd3b6deadba70 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
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;
}
|