class ManagedCallback;
class Protocol;
-struct Member;
-
enum ValueKind
{
ValueIsScope,
std::vector<Breakpoint> &breakpoints);
};
-class Debugger
+class Variables
{
-public:
- enum StepType {
- STEP_IN = 0,
- STEP_OVER,
- STEP_OUT
- };
-
-private:
- friend class ManagedCallback;
- enum ProcessAttachedState
- {
- ProcessAttached,
- ProcessUnattached
- };
- std::mutex m_processAttachedMutex;
- std::condition_variable m_processAttachedCV;
- ProcessAttachedState m_processAttachedState;
-
- void NotifyProcessCreated();
- void NotifyProcessExited();
- void WaitProcessExited();
- HRESULT CheckNoProcess();
-
- std::mutex m_lastStoppedThreadIdMutex;
- int m_lastStoppedThreadId;
-
- void SetLastStoppedThread(ICorDebugThread *pThread);
-
- Modules m_modules;
- Evaluator m_evaluator;
- Breakpoints m_breakpoints;
- Protocol *m_protocol;
- ToRelease<ManagedCallback> m_managedCallback;
- ICorDebug *m_pDebug;
- ICorDebugProcess *m_pProcess;
-
- bool m_justMyCode;
-
- std::mutex m_startupMutex;
- std::condition_variable m_startupCV;
- bool m_startupReady;
- HRESULT m_startupResult;
-
- PVOID m_unregisterToken;
- DWORD m_processId;
- std::string m_clrPath;
-
struct VariableReference
{
uint32_t variablesReference; // key
bool IsScope() const { return valueKind == ValueIsScope; }
VariableReference(VariableReference &&that) = default;
- private:
VariableReference(const VariableReference &that) = delete;
};
+
+ Evaluator &m_evaluator;
+
std::unordered_map<uint32_t, VariableReference> m_variables;
uint32_t m_nextVariableReference;
void AddVariableReference(Variable &variable, uint64_t frameId, ICorDebugValue *value, ValueKind valueKind);
- static VOID StartupCallback(IUnknown *pCordb, PVOID parameter, HRESULT hr);
- HRESULT Startup(IUnknown *punk, int pid);
-
- void Cleanup();
+ HRESULT GetStackVariables(
+ uint64_t frameId,
+ ICorDebugThread *pThread,
+ ICorDebugFrame *pFrame,
+ int start,
+ int count,
+ std::vector<Variable> &variables);
- static HRESULT DisableAllSteppers(ICorDebugProcess *pProcess);
+ HRESULT GetChildren(
+ VariableReference &ref,
+ ICorDebugThread *pThread,
+ ICorDebugFrame *pFrame,
+ int start,
+ int count,
+ std::vector<Variable> &variables);
- HRESULT SetupStep(ICorDebugThread *pThread, StepType stepType);
+ struct Member;
- HRESULT GetStackVariables(uint64_t frameId, ICorDebugThread *pThread, ICorDebugFrame *pFrame, int start, int count, std::vector<Variable> &variables);
- HRESULT GetChildren(VariableReference &ref, ICorDebugThread *pThread, ICorDebugFrame *pFrame, int start, int count, std::vector<Variable> &variables);
+ static void FixupInheritedFieldNames(std::vector<Member> &members);
HRESULT FetchFieldsAndProperties(
ICorDebugValue *pInputValue,
unsigned int &numchild,
bool static_members = false);
+public:
+
+ Variables(Evaluator &evaluator) : m_evaluator(evaluator), m_nextVariableReference(1) {}
+
+ int GetNamedVariables(uint32_t variablesReference);
+
+ HRESULT Variables::GetVariables(
+ ICorDebugProcess *pProcess,
+ uint32_t variablesReference,
+ VariablesFilter filter,
+ int start,
+ int count,
+ std::vector<Variable> &variables);
+
+ HRESULT GetScopes(ICorDebugProcess *pProcess, uint64_t frameId, std::vector<Scope> &scopes);
+
+ HRESULT Evaluate(ICorDebugProcess *pProcess, uint64_t frameId, const std::string &expression, Variable &variable);
+};
+
+class Debugger
+{
+public:
+ enum StepType {
+ STEP_IN = 0,
+ STEP_OVER,
+ STEP_OUT
+ };
+
+private:
+ friend class ManagedCallback;
+ enum ProcessAttachedState
+ {
+ ProcessAttached,
+ ProcessUnattached
+ };
+ std::mutex m_processAttachedMutex;
+ std::condition_variable m_processAttachedCV;
+ ProcessAttachedState m_processAttachedState;
+
+ void NotifyProcessCreated();
+ void NotifyProcessExited();
+ void WaitProcessExited();
+ HRESULT CheckNoProcess();
+
+ std::mutex m_lastStoppedThreadIdMutex;
+ int m_lastStoppedThreadId;
+
+ void SetLastStoppedThread(ICorDebugThread *pThread);
+
+ Modules m_modules;
+ Evaluator m_evaluator;
+ Breakpoints m_breakpoints;
+ Variables m_variables;
+ Protocol *m_protocol;
+ ToRelease<ManagedCallback> m_managedCallback;
+ ICorDebug *m_pDebug;
+ ICorDebugProcess *m_pProcess;
+
+ bool m_justMyCode;
+
+ std::mutex m_startupMutex;
+ std::condition_variable m_startupCV;
+ bool m_startupReady;
+ HRESULT m_startupResult;
+
+ PVOID m_unregisterToken;
+ DWORD m_processId;
+ std::string m_clrPath;
+
+ static VOID StartupCallback(IUnknown *pCordb, PVOID parameter, HRESULT hr);
+ HRESULT Startup(IUnknown *punk, int pid);
+
+ void Cleanup();
+
+ static HRESULT DisableAllSteppers(ICorDebugProcess *pProcess);
+
+ HRESULT SetupStep(ICorDebugThread *pThread, StepType stepType);
+
HRESULT GetStackTrace(ICorDebugThread *pThread, int lowFrame, int highFrame, std::vector<StackFrame> &stackFrames);
HRESULT GetFrameLocation(ICorDebugFrame *pFrame, int threadId, uint32_t level, StackFrame &stackFrame);
public:
#include "frames.h"
-HRESULT Debugger::GetNumChild(
+HRESULT Variables::GetNumChild(
ICorDebugValue *pValue,
unsigned int &numchild,
bool static_members)
return S_OK;
}
-struct Member
+struct Variables::Member
{
std::string name;
std::string ownerType;
value(std::move(value))
{}
Member(Member &&that) = default;
-private:
Member(const Member &that) = delete;
};
-HRESULT Debugger::FetchFieldsAndProperties(
+HRESULT Variables::FetchFieldsAndProperties(
ICorDebugValue *pInputValue,
ICorDebugThread *pThread,
ICorDebugILFrame *pILFrame,
}
int Debugger::GetNamedVariables(uint32_t variablesReference)
+{
+ return m_variables.GetNamedVariables(variablesReference);
+}
+
+int Variables::GetNamedVariables(uint32_t variablesReference)
{
auto it = m_variables.find(variablesReference);
if (it == m_variables.end())
return it->second.namedVariables;
}
-HRESULT Debugger::GetVariables(uint32_t variablesReference, VariablesFilter filter, int start, int count, std::vector<Variable> &variables)
+HRESULT Debugger::GetVariables(
+ uint32_t variablesReference,
+ VariablesFilter filter,
+ int start,
+ int count,
+ std::vector<Variable> &variables)
+{
+ return m_variables.GetVariables(m_pProcess, variablesReference, filter, start, count, variables);
+}
+
+HRESULT Variables::GetVariables(
+ ICorDebugProcess *pProcess,
+ uint32_t variablesReference,
+ VariablesFilter filter,
+ int start,
+ int count,
+ std::vector<Variable> &variables)
{
+ if (pProcess == nullptr)
+ return E_FAIL;
+
auto it = m_variables.find(variablesReference);
if (it == m_variables.end())
return E_FAIL;
StackFrame stackFrame(ref.frameId);
ToRelease<ICorDebugThread> pThread;
- IfFailRet(m_pProcess->GetThread(stackFrame.GetThreadId(), &pThread));
+ IfFailRet(pProcess->GetThread(stackFrame.GetThreadId(), &pThread));
ToRelease<ICorDebugFrame> pFrame;
IfFailRet(GetFrameAt(pThread, stackFrame.GetLevel(), &pFrame));
return S_OK;
}
-void Debugger::AddVariableReference(Variable &variable, uint64_t frameId, ICorDebugValue *value, ValueKind valueKind)
+void Variables::AddVariableReference(Variable &variable, uint64_t frameId, ICorDebugValue *value, ValueKind valueKind)
{
HRESULT Status;
unsigned int numChild = 0;
m_variables.emplace(std::make_pair(variable.variablesReference, std::move(variableReference)));
}
-HRESULT Debugger::GetStackVariables(uint64_t frameId, ICorDebugThread *pThread, ICorDebugFrame *pFrame, int start, int count, std::vector<Variable> &variables)
+HRESULT Variables::GetStackVariables(
+ uint64_t frameId,
+ ICorDebugThread *pThread,
+ ICorDebugFrame *pFrame,
+ int start,
+ int count,
+ std::vector<Variable> &variables)
{
HRESULT Status;
HRESULT Debugger::GetScopes(uint64_t frameId, std::vector<Scope> &scopes)
{
+ return m_variables.GetScopes(m_pProcess, frameId, scopes);
+}
+
+HRESULT Variables::GetScopes(ICorDebugProcess *pProcess, uint64_t frameId, std::vector<Scope> &scopes)
+{
+ if (pProcess == nullptr)
+ return E_FAIL;
+
HRESULT Status;
StackFrame stackFrame(frameId);
ToRelease<ICorDebugThread> pThread;
- IfFailRet(m_pProcess->GetThread(stackFrame.GetThreadId(), &pThread));
+ IfFailRet(pProcess->GetThread(stackFrame.GetThreadId(), &pThread));
ToRelease<ICorDebugFrame> pFrame;
IfFailRet(GetFrameAt(pThread, stackFrame.GetLevel(), &pFrame));
return S_OK;
}
-static void FixupInheritedFieldNames(std::vector<Member> &members)
+void Variables::FixupInheritedFieldNames(std::vector<Member> &members)
{
std::unordered_set<std::string> names;
for (auto &it : members)
}
}
-HRESULT Debugger::GetChildren(VariableReference &ref,
- ICorDebugThread *pThread,
- ICorDebugFrame *pFrame,
- int start,
- int count,
- std::vector<Variable> &variables)
+HRESULT Variables::GetChildren(
+ VariableReference &ref,
+ ICorDebugThread *pThread,
+ ICorDebugFrame *pFrame,
+ int start,
+ int count,
+ std::vector<Variable> &variables)
{
if (ref.IsScope())
return E_INVALIDARG;
HRESULT Debugger::Evaluate(uint64_t frameId, const std::string &expression, Variable &variable)
{
+ return m_variables.Evaluate(m_pProcess, frameId, expression, variable);
+}
+
+HRESULT Variables::Evaluate(
+ ICorDebugProcess *pProcess,
+ uint64_t frameId,
+ const std::string &expression,
+ Variable &variable)
+{
+ if (pProcess == nullptr)
+ return E_FAIL;
+
HRESULT Status;
StackFrame stackFrame(frameId);
ToRelease<ICorDebugThread> pThread;
- IfFailRet(m_pProcess->GetThread(stackFrame.GetThreadId(), &pThread));
+ IfFailRet(pProcess->GetThread(stackFrame.GetThreadId(), &pThread));
ToRelease<ICorDebugFrame> pFrame;
IfFailRet(GetFrameAt(pThread, stackFrame.GetLevel(), &pFrame));