-
Notifications
You must be signed in to change notification settings - Fork 106
/
Copy pathstepper_simple.cpp
140 lines (108 loc) · 4.26 KB
/
stepper_simple.cpp
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// Copyright (c) 2021 Samsung Electronics Co., LTD
// Distributed under the MIT License.
// See the LICENSE file in the project root for more information.
#include "debugger/stepper_simple.h"
#include "debugger/threads.h"
#include "interfaces/idebugger.h"
#include "metadata/modules.h"
namespace netcoredbg
{
HRESULT SimpleStepper::SetupStep(ICorDebugThread *pThread, IDebugger::StepType stepType)
{
HRESULT Status;
ToRelease<ICorDebugStepper> pStepper;
IfFailRet(pThread->CreateStepper(&pStepper));
CorDebugIntercept mask = (CorDebugIntercept)(INTERCEPT_ALL & ~(INTERCEPT_SECURITY | INTERCEPT_CLASS_INIT));
IfFailRet(pStepper->SetInterceptMask(mask));
CorDebugUnmappedStop stopMask = STOP_NONE;
IfFailRet(pStepper->SetUnmappedStopMask(stopMask));
ToRelease<ICorDebugStepper2> pStepper2;
IfFailRet(pStepper->QueryInterface(IID_ICorDebugStepper2, (LPVOID *)&pStepper2));
// Note, we use JMC in runtime all the time (same behaviour as MS vsdbg and MSVS debugger have),
// since this is the only way provide good speed for stepping in case "JMC disabled".
// But in case "JMC disabled", debugger must care about different logic for exceptions/stepping/breakpoints.
IfFailRet(pStepper2->SetJMC(TRUE));
ThreadId threadId(getThreadId(pThread));
if (stepType == IDebugger::STEP_OUT)
{
IfFailRet(pStepper->StepOut());
std::lock_guard<std::mutex> lock(m_stepMutex);
m_enabledSimpleStepId = int(threadId);
return S_OK;
}
BOOL bStepIn = stepType == IDebugger::STEP_IN;
COR_DEBUG_STEP_RANGE range;
if (SUCCEEDED(m_sharedModules->GetStepRangeFromCurrentIP(pThread, &range)))
{
IfFailRet(pStepper->StepRange(bStepIn, &range, 1));
} else {
IfFailRet(pStepper->Step(bStepIn));
}
std::lock_guard<std::mutex> lock(m_stepMutex);
m_enabledSimpleStepId = int(threadId);
return S_OK;
}
HRESULT SimpleStepper::ManagedCallbackBreakpoint(ICorDebugAppDomain *pAppDomain, ICorDebugThread *pThread)
{
ThreadId threadId(getThreadId(pThread));
auto stepForcedIgnoreBP = [&]()
{
{
std::lock_guard<std::mutex> lock(m_stepMutex);
if (m_enabledSimpleStepId != int(threadId))
{
return false;
}
}
ToRelease<ICorDebugStepperEnum> steppers;
if (FAILED(pAppDomain->EnumerateSteppers(&steppers)))
return false;
ICorDebugStepper *curStepper;
ULONG steppersFetched;
while (SUCCEEDED(steppers->Next(1, &curStepper, &steppersFetched)) && steppersFetched == 1)
{
BOOL pbActive;
ToRelease<ICorDebugStepper> pStepper(curStepper);
if (SUCCEEDED(pStepper->IsActive(&pbActive)) && pbActive)
return false;
}
return true;
};
if (stepForcedIgnoreBP())
return S_OK;
return S_FALSE; // S_FALSE - no error, but steppers not affect on callback
}
HRESULT SimpleStepper::ManagedCallbackStepComplete()
{
// Reset simple step without real stepper release.
m_stepMutex.lock();
m_enabledSimpleStepId = 0;
m_stepMutex.unlock();
return S_FALSE; // S_FALSE - no error, but steppers not affect on callback
}
HRESULT SimpleStepper::DisableAllSteppers(ICorDebugProcess *pProcess)
{
HRESULT Status;
ToRelease<ICorDebugAppDomainEnum> domains;
IfFailRet(pProcess->EnumerateAppDomains(&domains));
ICorDebugAppDomain *curDomain;
ULONG domainsFetched;
while (SUCCEEDED(domains->Next(1, &curDomain, &domainsFetched)) && domainsFetched == 1)
{
ToRelease<ICorDebugAppDomain> pDomain(curDomain);
ToRelease<ICorDebugStepperEnum> steppers;
IfFailRet(pDomain->EnumerateSteppers(&steppers));
ICorDebugStepper *curStepper;
ULONG steppersFetched;
while (SUCCEEDED(steppers->Next(1, &curStepper, &steppersFetched)) && steppersFetched == 1)
{
ToRelease<ICorDebugStepper> pStepper(curStepper);
pStepper->Deactivate();
}
}
m_stepMutex.lock();
m_enabledSimpleStepId = 0;
m_stepMutex.unlock();
return S_OK;
}
} // namespace netcoredbg