HRESULT CordbValue::CreateBreakpoint(ICorDebugValueBreakpoint **ppBreakpoint)
{
+ //PUBLIC_API_ENTRY(this);
+ //FAIL_IF_NEUTERED(this);
+ //ATT_REQUIRE_STOPPED_MAY_FAIL(GetProcess());
VALIDATE_POINTER_TO_OBJECT(ppBreakpoint, ICorDebugValueBreakpoint **);
- return E_NOTIMPL;
+ //ICorDebugHandleValue** ppHandleValue = nullptr;
+ //if (SUCCEEDED(InternalCreateHandle((CorDebugHandleType)3, ppHandleValue)))
+ //{
+ return GetProcess()->CreateBreakpoint((CORDB_ADDRESS)this->m_id, ppBreakpoint);
+ //}
+
+ //return E_NOTIMPL;
} // CordbValue::CreateBreakpoint
// gets the exact type of a value
*ppHandle = NULL;
- if (handleType == HANDLE_STRONG)
+ if (handleType == 3)
+ {
+ fStrong = 2;
+ }
+ else if (handleType == HANDLE_STRONG)
{
fStrong = TRUE;
}
m_syncCompleteReceived(false),
m_pShim(pShim),
m_userThreads(11),
+ m_dataBreakpoints(4),
m_oddSync(false),
#ifdef FEATURE_INTEROP_DEBUGGING
m_unmanagedThreads(11),
// Sweep neuter lists.
m_ExitNeuterList.NeuterAndClear(this);
m_ContinueNeuterList.NeuterAndClear(this);
+ m_dataBreakpoints.NeuterAndClear(GetProcessLock());
m_userThreads.NeuterAndClear(GetProcessLock());
{
*pInterface = static_cast<ICorDebugProcess8*>(this);
}
+ else if (id == IID_ICorDebugProcess9)
+ {
+ *pInterface = static_cast<ICorDebugProcess9*>(this);
+ }
#ifdef FEATURE_LEGACYNETCF_DBG_HOST_CONTROL
else if (id == IID_ICorDebugLegacyNetCFHostCallbackInvoker_PrivateWindowsPhoneOnly)
{
return hr;
}
+COM_METHOD CordbProcess::CreateBreakpoint(CORDB_ADDRESS address, ICorDebugValueBreakpoint **ppBreakpoint)
+{
+ HRESULT hr = S_OK;
+ PUBLIC_API_ENTRY(this);
+ FAIL_IF_NEUTERED(this);
+ ATT_REQUIRE_STOPPED_MAY_FAIL(this);
+
+ RSLockHolder lockHolder(GetProcessLock());
+ HASHFIND hashFind;
+ CordbThread * pThread;
+
+ for (pThread = m_userThreads.FindFirst(&hashFind);
+ pThread != NULL;
+ pThread = m_userThreads.FindNext(&hashFind))
+ {
+ HRESULT hr = S_OK;
+ HANDLE hTemp;
+ EX_TRY
+ {
+ pThread->InternalGetHandle(&hTemp); // throws on error
+ }
+ EX_CATCH_HRESULT(hr);
+
+ DWORD dwDesiredAccess = THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION | THREAD_SET_CONTEXT | THREAD_SET_INFORMATION | THREAD_SUSPEND_RESUME | THREAD_TERMINATE;
+
+ HANDLE hThread;
+ hr = ::DuplicateHandle(GetCurrentProcess(), hTemp, GetCurrentProcess(), &hThread, dwDesiredAccess, FALSE, 0);
+
+ if (SUCCEEDED(hr))
+ {
+ DWORD dwSuspendCount = ::SuspendThread(hThread);
+
+ CONTEXT context;
+ context.ContextFlags = CONTEXT_CONTROL | CONTEXT_DEBUG_REGISTERS;
+
+ BOOL result = ::GetThreadContext(hThread, &context);
+
+ if (result == TRUE)
+ {
+#ifdef DBG_TARGET_AMD64
+ if (m_dataBreakpoints.GetCount() == 0)
+ {
+ context.Dr0 = address;
+ PDR7 pdr7 = (PDR7)&(context.Dr7);
+ pdr7->Len0 = 2;
+ pdr7->Rwe0 = 0x01;
+ pdr7->L0 = 0x01;
+ }
+ else if (m_dataBreakpoints.GetCount() == 1)
+ {
+ context.Dr1 = address;
+ PDR7 pdr7 = (PDR7)&(context.Dr7);
+ pdr7->Len1 = 2;
+ pdr7->Rwe1 = 0x01;
+ pdr7->L1 = 0x01;
+ }
+ else if (m_dataBreakpoints.GetCount() == 2)
+ {
+ context.Dr2 = address;
+ PDR7 pdr7 = (PDR7)&(context.Dr7);
+ pdr7->Len2 = 2;
+ pdr7->Rwe2 = 0x01;
+ pdr7->L2 = 0x01;
+ }
+ else if (m_dataBreakpoints.GetCount() == 3)
+ {
+ context.Dr3 = address;
+ PDR7 pdr7 = (PDR7)&(context.Dr7);
+ pdr7->Len3 = 2;
+ pdr7->Rwe3 = 0x01;
+ pdr7->L3 = 0x01;
+ }
+ else
+ {
+ return E_FAIL;
+ }
+#endif
+ }
+ result = ::SetThreadContext(hThread, &context);
+ ::ResumeThread(hThread);
+ }
+ }
+
+ EX_TRY
+ {
+ RSInitHolder<CordbValueBreakpoint> pValueBreakpoint(new CordbValueBreakpoint(m_dataBreakpoints.GetCount(), nullptr, this));
+
+ if (pValueBreakpoint)
+ {
+ hr = pValueBreakpoint->QueryInterface(IID_ICorDebugValueBreakpoint, (void**)ppBreakpoint);
+ }
+
+ pValueBreakpoint.TransferOwnershipToHash(&m_dataBreakpoints);
+ }
+ EX_CATCH_HRESULT(hr);
+
+ return hr;
+}
+
#ifdef FEATURE_LEGACYNETCF_DBG_HOST_CONTROL
COM_METHOD CordbProcess::InvokePauseCallback()
}
break;
+ case DB_IPCE_DATA_BREAKPOINT:
+ {
+ _ASSERTE(pThread != NULL);
+ _ASSERTE(pAppDomain != NULL);
+
+ HASHFIND hashFind;
+ CordbValueBreakpoint* pBreakpoint;
+
+ for (pBreakpoint = m_dataBreakpoints.FindFirst(&hashFind);
+ pBreakpoint != NULL;
+ pBreakpoint = m_dataBreakpoints.FindNext(&hashFind))
+ {
+ if (pBreakpoint->GetIndex() == pEvent->DataBreakpointData.index)
+ {
+ PUBLIC_CALLBACK_IN_THIS_SCOPE2(this, pLockHolder, pEvent, "thread=0x%p, bp=0x%p", pThread, pBreakpoint);
+ pCallback1->Breakpoint(pAppDomain, pThread, CordbBreakpointToInterface(pBreakpoint));
+ break;
+ }
+ }
+ }
+ break;
case DB_IPCE_USER_BREAKPOINT:
{
STRESS_LOG1(LF_CORDB, LL_INFO1000, "[%x] RCET::DRCE: user breakpoint.\n",
class CordbContext;
class CordbThread;
class CordbVariableHome;
+class CordbValueBreakpoint;
#ifdef FEATURE_INTEROP_DEBUGGING
class CordbUnmanagedThread;
class CordbSafeHashTable;
+typedef struct _DR7 *PDR7;
+typedef struct _DR7 {
+ DWORD L0 : 1;
+ DWORD G0 : 1;
+ DWORD L1 : 1;
+ DWORD G1 : 1;
+ DWORD L2 : 1;
+ DWORD G2 : 1;
+ DWORD L3 : 1;
+ DWORD G3 : 1;
+ DWORD LE : 1;
+ DWORD GE : 1;
+ DWORD Pad1 : 3;
+ DWORD GD : 1;
+ DWORD Pad2 : 1;
+ DWORD Pad3 : 1;
+ DWORD Rwe0 : 2;
+ DWORD Len0 : 2;
+ DWORD Rwe1 : 2;
+ DWORD Len1 : 2;
+ DWORD Rwe2 : 2;
+ DWORD Len2 : 2;
+ DWORD Rwe3 : 2;
+ DWORD Len3 : 2;
+} DR7;
+
//---------------------------------------------------------------------------------------
//
// This is an encapsulation of the information necessary to connect to the debugger proxy on a remote machine.
public ICorDebugProcess5,
public ICorDebugProcess7,
public ICorDebugProcess8,
+ public ICorDebugProcess9,
public IDacDbiInterface::IAllocator,
public IDacDbiInterface::IMetaDataLookup,
public IProcessShimHooks
//-----------------------------------------------------------
COM_METHOD EnableExceptionCallbacksOutsideOfMyCode(BOOL enableExceptionsOutsideOfJMC);
+ COM_METHOD CreateBreakpoint(CORDB_ADDRESS address, ICorDebugValueBreakpoint **ppBreakpoint);
+
#ifdef FEATURE_LEGACYNETCF_DBG_HOST_CONTROL
// ---------------------------------------------------------------
// ICorDebugLegacyNetCFHostCallbackInvoker_PrivateWindowsPhoneOnly
// This is just used for backwards compat.
CORDB_ADDRESS m_clrInstanceId;
+ CordbSafeHashTable<CordbValueBreakpoint> m_dataBreakpoints;
+
// List of things that get neutered on process exit and Continue respectively.
NeuterList m_ExitNeuterList;
NeuterList m_ContinueNeuterList;
public ICorDebugValueBreakpoint
{
public:
- CordbValueBreakpoint(CordbValue *pValue);
+ CordbValueBreakpoint(unsigned int index, CordbValue *pValue, CordbProcess* pProcess): CordbBreakpoint(pProcess, CordbBreakpointType::CBT_VALUE)
+ {
+ m_value = pValue;
+ m_index = index;
+ }
#ifdef _DEBUG
{
return (BaseRelease());
}
- COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
+ COM_METHOD QueryInterface(REFIID riid, void **ppInterface)
+ {
+ if (riid == IID_ICorDebugValueBreakpoint)
+ {
+ *ppInterface = static_cast<ICorDebugValueBreakpoint*>(this);
+ }
+ else if (riid == IID_ICorDebugBreakpoint)
+ {
+ *ppInterface = static_cast<ICorDebugBreakpoint*>(static_cast<CordbBreakpoint*>(this));
+ }
+ else if (riid == IID_IUnknown)
+ {
+ *ppInterface = static_cast<IUnknown *>(static_cast<ICorDebugValueBreakpoint*>(this));
+ }
+ else
+ {
+ return E_NOINTERFACE;
+ }
+
+ ExternalAddRef();
+ return S_OK;
+ }
//-----------------------------------------------------------
// ICorDebugValueBreakpoint
//-----------------------------------------------------------
- COM_METHOD GetValue(ICorDebugValue **ppValue);
- COM_METHOD Activate(BOOL bActive);
+ COM_METHOD GetValue(ICorDebugValue **ppValue)
+ {
+ return S_OK;
+ }
+
+ COM_METHOD Activate(BOOL bActive)
+ {
+ return S_OK;
+ }
+
COM_METHOD IsActive(BOOL *pbActive)
{
VALIDATE_POINTER_TO_OBJECT(pbActive, BOOL *);
// Non-COM methods
//-----------------------------------------------------------
- void Disconnect();
+ void Disconnect()
+ {
+ }
+
+ unsigned int GetIndex()
+ {
+ return m_index;
+ }
public:
CordbValue *m_value;
+
+private:
+ unsigned int m_index;
};
/* ------------------------------------------------------------------------- *
DebuggerControllerPage *DebuggerController::g_protections = NULL;
CrstStatic DebuggerController::g_criticalSection;
int DebuggerController::g_cTotalMethodEnter = 0;
-
+DebuggerDataBreakpoint *DebuggerDataBreakpoint::g_DataBreakpoints[4];
+unsigned int DebuggerDataBreakpoint::g_DataBreakpointCount = 0;
// Is this patch at a position at which it's safe to take a stack?
bool DebuggerControllerPatch::IsSafeForStackTrace()
}
if (stWhat & ST_SINGLE_STEP &&
+ tpr != TPR_TRIGGER_ONLY_THIS && DebuggerDataBreakpoint::g_DataBreakpointCount > 0)
+ {
+ for (unsigned int i = 0; i < DebuggerDataBreakpoint::g_DataBreakpointCount; i++)
+ {
+ LOG((LF_CORDB, LL_INFO10000, "DC::SFT: Trigger data breakpoint controller\n"));
+
+ if (DebuggerDataBreakpoint::g_DataBreakpoints[i]->TriggerDataBreakpoint(thread, context))
+ {
+ pDcq->dcqEnqueue(DebuggerDataBreakpoint::g_DataBreakpoints[i], FALSE);
+ }
+ }
+ }
+
+ if (stWhat & ST_SINGLE_STEP &&
tpr != TPR_TRIGGER_ONLY_THIS)
{
LOG((LF_CORDB, LL_INFO10000, "DC::SFT: Trigger controllers with single step\n"));
reabort = thread->m_StateNC & Thread::TSNC_DebuggerReAbort;
SENDIPCEVENT_END;
+ CONTEXT c;
+ c.ContextFlags = CONTEXT_DEBUG_REGISTERS;
+ thread->GetThreadContext(&c);
+
+ context->Dr7 = c.Dr7;
+ context->Dr0 = c.Dr0;
+ context->Dr1 = c.Dr1;
+ context->Dr2 = c.Dr2;
+ context->Dr3 = c.Dr3;
+
+ if (context->Dr0 != NULL && DebuggerDataBreakpoint::g_DataBreakpointCount == 0)
+ {
+ DebuggerDataBreakpoint::CreateDebuggerDataBreakpoint(thread, thread->GetDomain(), context);
+ }
+
+ if (context->Dr1 != NULL && DebuggerDataBreakpoint::g_DataBreakpointCount == 1)
+ {
+ DebuggerDataBreakpoint::CreateDebuggerDataBreakpoint(thread, thread->GetDomain(), context);
+ }
+
+ if (context->Dr2 != NULL && DebuggerDataBreakpoint::g_DataBreakpointCount == 2)
+ {
+ DebuggerDataBreakpoint::CreateDebuggerDataBreakpoint(thread, thread->GetDomain(), context);
+ }
+
+ if (context->Dr3 != NULL && DebuggerDataBreakpoint::g_DataBreakpointCount == 3)
+ {
+ DebuggerDataBreakpoint::CreateDebuggerDataBreakpoint(thread, thread->GetDomain(), context);
+ }
+
if (!atSafePlace)
g_pDebugger->DecThreadsAtUnsafePlaces();
class DebuggerUserBreakpoint;
class ControllerStackInfo;
+typedef struct _DR6 *PDR6;
+typedef struct _DR6 {
+ DWORD B0 : 1;
+ DWORD B1 : 1;
+ DWORD B2 : 1;
+ DWORD B3 : 1;
+ DWORD Pad1 : 9;
+ DWORD BD : 1;
+ DWORD BS : 1;
+ DWORD BT : 1;
+} DR6;
+
+typedef struct _DR7 *PDR7;
+typedef struct _DR7 {
+ DWORD L0 : 1;
+ DWORD G0 : 1;
+ DWORD L1 : 1;
+ DWORD G1 : 1;
+ DWORD L2 : 1;
+ DWORD G2 : 1;
+ DWORD L3 : 1;
+ DWORD G3 : 1;
+ DWORD LE : 1;
+ DWORD GE : 1;
+ DWORD Pad1 : 3;
+ DWORD GD : 1;
+ DWORD Pad2 : 1;
+ DWORD Pad3 : 1;
+ DWORD Rwe0 : 2;
+ DWORD Len0 : 2;
+ DWORD Rwe1 : 2;
+ DWORD Len1 : 2;
+ DWORD Rwe2 : 2;
+ DWORD Len2 : 2;
+ DWORD Rwe3 : 2;
+ DWORD Len3 : 2;
+} DR7;
+
+
// Ticket for ensuring that it's safe to get a stack trace.
class StackTraceTicket
{
// send that they've hit a user breakpoint to the Right Side.
DEBUGGER_CONTROLLER_JMC_STEPPER, // Stepper that only stops in JMC-functions.
DEBUGGER_CONTROLLER_CONTINUABLE_EXCEPTION,
+ DEBUGGER_CONTROLLER_DATA_BREAKPOINT,
DEBUGGER_CONTROLLER_STATIC,
};
// DebuggerController: DebuggerController serves
// both as a static class that dispatches exceptions coming from the
-// EE, and as an abstract base class for the five classes that derrive
+// EE, and as an abstract base class for the five classes that derive
// from it.
class DebuggerController
{
bool SendEvent(Thread *thread, bool fInteruptedBySetIp);
};
+class DebuggerDataBreakpoint : public DebuggerController
+{
+public:
+ static void CreateDebuggerDataBreakpoint(Thread* pThread, AppDomain* pAppDomain, CONTEXT* context)
+ {
+ _ASSERTE(g_DataBreakpointCount < 5);
+
+ DebuggerDataBreakpoint* newDataBp = new DebuggerDataBreakpoint(g_DataBreakpointCount, pThread, pAppDomain, context);
+ g_DataBreakpoints[g_DataBreakpointCount++] = newDataBp;
+ }
+
+ DebuggerDataBreakpoint(unsigned int index, Thread* pThread, AppDomain* pAppDomain, CONTEXT* context) : DebuggerController(pThread, pAppDomain)
+ {
+ LOG((LF_CORDB, LL_INFO10000, "D::DDBP: New Data Breakpoint set for 0x%x\n", context->Dr0));
+ memcpy(&m_Context, context, sizeof(CONTEXT));
+ m_Index = index;
+ }
+
+ virtual DEBUGGER_CONTROLLER_TYPE GetDCType(void)
+ {
+ return DEBUGGER_CONTROLLER_DATA_BREAKPOINT;
+ }
+
+ bool SendEvent(Thread *thread, bool fInteruptedBySetIp)
+ {
+ CONTRACTL
+ {
+ SO_NOT_MAINLINE;
+ NOTHROW;
+ SENDEVENT_CONTRACT_ITEMS;
+ }
+ CONTRACTL_END;
+
+ LOG((LF_CORDB, LL_INFO10000, "DDBP::SE: in DebuggerDataBreakpoint's SendEvent\n"));
+
+ CONTEXT *context = g_pEEInterface->GetThreadFilterContext(thread);
+
+ // If we got interupted by SetIp, we just don't send the IPC event. Our triggers are still
+ // active so no harm done.
+ if (!fInteruptedBySetIp)
+ {
+ g_pDebugger->SendDataBreakpoint(thread, context, this);
+ return true;
+ }
+
+ // Controller is still alive, will fire if we hit the breakpoint again.
+ return false;
+ }
+
+ bool TriggerDataBreakpoint(Thread *thread, CONTEXT * pContext)
+ {
+ LOG((LF_CORDB, LL_INFO10000, "D::DDBP: Doing TriggerDataBreakpoint...\n"));
+
+ bool hitDataBp = false;
+
+ PDR6 pdr6 = (PDR6)&(pContext->Dr6);
+ PDR7 pdr7 = (PDR7)&(pContext->Dr7);
+
+ if (m_Index == 0)
+ {
+ if (pdr6->B0)
+ {
+ if (pContext->Dr0 == m_Context.Dr0 && pdr7->L0 != 0)
+ {
+ hitDataBp = true;
+ }
+ }
+ }
+ else if (m_Index == 1)
+ {
+ if (pdr6->B1)
+ {
+ if (pContext->Dr1 == m_Context.Dr1 && pdr7->L1 != 0)
+ {
+ hitDataBp = true;
+ }
+ }
+ }
+ else if (m_Index == 2)
+ {
+ if (pdr6->B2)
+ {
+ if (pContext->Dr2 == m_Context.Dr2 && pdr7->L2 != 0)
+ {
+ hitDataBp = true;
+ }
+ }
+ }
+ else if (m_Index == 3)
+ {
+ if (pdr6->B3)
+ {
+ if (pContext->Dr3 == m_Context.Dr3 && pdr7->L3 != 0)
+ {
+ hitDataBp = true;
+ }
+ }
+ }
+
+ if (hitDataBp)
+ {
+ LOG((LF_CORDB, LL_INFO10000, "D::DDBP: HIT DATA BREAKPOINT...\n"));
+ }
+ else
+ {
+ LOG((LF_CORDB, LL_INFO10000, "D::DDBP: DIDN'T TRIGGER DATA BREAKPOINT...\n"));
+ }
+
+ return hitDataBp;
+ }
+
+ unsigned int GetIndex()
+ {
+ return m_Index;
+ }
+
+ static DebuggerDataBreakpoint* g_DataBreakpoints[4];
+ static unsigned int g_DataBreakpointCount;
+private:
+ CONTEXT m_Context;
+ unsigned int m_Index;
+};
+
+
/* ------------------------------------------------------------------------- *
* DebuggerUserBreakpoint routines. UserBreakpoints are used
* by Runtime threads to send that they've hit a user breakpoint to the
bool SendEvent(Thread *thread, bool fInteruptedBySetIp);
};
+
#ifdef EnC_SUPPORTED
//---------------------------------------------------------------------------------------
//
return (m_threadsAtUnsafePlaces != 0);
}
+void Debugger::SendDataBreakpoint(Thread *thread, CONTEXT *context,
+ DebuggerDataBreakpoint *breakpoint)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ }
+ CONTRACTL_END;
+
+ if (CORDBUnrecoverableError(this))
+ return;
+
+#ifdef _DEBUG
+ static BOOL shouldBreak = -1;
+ if (shouldBreak == -1)
+ shouldBreak = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_DbgBreakOnSendBreakpoint);
+
+ if (shouldBreak > 0) {
+ _ASSERTE(!"DbgBreakOnSendBreakpoint");
+ }
+#endif
+
+ LOG((LF_CORDB, LL_INFO10000, "D::SDB: breakpoint BP:0x%x\n", breakpoint));
+
+ _ASSERTE((g_pEEInterface->GetThread() &&
+ !g_pEEInterface->GetThread()->m_fPreemptiveGCDisabled) ||
+ g_fInControlC);
+
+ _ASSERTE(ThreadHoldsLock());
+
+ // Send a breakpoint event to the Right Side
+ DebuggerIPCEvent* ipce = m_pRCThread->GetIPCEventSendBuffer();
+ InitIPCEvent(ipce,
+ DB_IPCE_DATA_BREAKPOINT,
+ thread,
+ thread->GetDomain());
+ ipce->DataBreakpointData.index = breakpoint->GetIndex();
+ _ASSERTE(breakpoint->m_pAppDomain == ipce->vmAppDomain.GetRawPtr());
+
+ m_pRCThread->SendIPCEvent();
+}
+
//
// SendBreakpoint is called by Runtime threads to send that they've
// hit a breakpoint to the Right Side.
Object * pObject = (Object*)pEvent->CreateHandle.objectToken;
OBJECTREF objref = ObjectToOBJECTREF(pObject);
AppDomain * pAppDomain = pEvent->vmAppDomain.GetRawPtr();
- BOOL fStrong = pEvent->CreateHandle.fStrong;
+ int fStrong = (int) pEvent->CreateHandle.fStrong;
OBJECTHANDLE objectHandle;
// This is a synchronous event (reply required)
// create strong handle
objectHandle = pAppDomain->CreateStrongHandle(objref);
}
+ else if (fStrong == 2)
+ {
+ objectHandle = pAppDomain->CreatePinningHandle(objref);
+ }
else
{
// create the weak long handle
//-----------------------------------------------------------------------------
// Execution control needs several ways to get at the context of a thread
-// stopped in mangaged code (stepping, setip, func-eval).
+// stopped in managed code (stepping, setip, func-eval).
// We want to abstract away a few things:
// - active: this thread is stopped at a patch
// - inactive: this threads was managed suspended somewhere in jitted code
void SendBreakpoint(Thread *thread, T_CONTEXT *context,
DebuggerBreakpoint *breakpoint);
+ void SendDataBreakpoint(Thread* thread, T_CONTEXT *context, DebuggerDataBreakpoint *breakpoint);
+
void SendStep(Thread *thread, T_CONTEXT *context,
DebuggerStepper *stepper,
CorDebugStepReason reason);
DEFINE_LSPTR_TYPE(class DebuggerMethodInfo, LSPTR_DMI);
DEFINE_LSPTR_TYPE(class MethodDesc, LSPTR_METHODDESC);
DEFINE_LSPTR_TYPE(class DebuggerBreakpoint, LSPTR_BREAKPOINT);
+DEFINE_LSPTR_TYPE(class DebuggerDataBreakpoint, LSPTR_DATA_BREAKPOINT);
DEFINE_LSPTR_TYPE(class DebuggerEval, LSPTR_DEBUGGEREVAL);
DEFINE_LSPTR_TYPE(class DebuggerStepper, LSPTR_STEPPER);
struct MSLAYOUT
{
+ unsigned int index;
+ } DataBreakpointData;
+
+ struct MSLAYOUT
+ {
LSPTR_STEPPER stepperToken;
VMPTR_Thread vmThreadToken;
FramePointer frameToken;
IPC_EVENT_TYPE1(DB_IPCE_METADATA_UPDATE ,0x015D)
IPC_EVENT_TYPE1(DB_IPCE_RESOLVE_UPDATE_METADATA_1_RESULT,0x015E)
IPC_EVENT_TYPE1(DB_IPCE_RESOLVE_UPDATE_METADATA_2_RESULT,0x015F)
-IPC_EVENT_TYPE0(DB_IPCE_RUNTIME_LAST ,0x0160) // The last event from runtime
+IPC_EVENT_TYPE1(DB_IPCE_DATA_BREAKPOINT ,0x0160)
+IPC_EVENT_TYPE0(DB_IPCE_RUNTIME_LAST ,0x0161) // The last event from runtime
IPC_EVENT_TYPE2(DB_IPCE_GET_GCHANDLE_INFO ,0x0251)
IPC_EVENT_TYPE2(DB_IPCE_RESOLVE_UPDATE_METADATA_1 ,0x0256)
IPC_EVENT_TYPE2(DB_IPCE_RESOLVE_UPDATE_METADATA_2 ,0x0257)
-IPC_EVENT_TYPE0(DB_IPCE_DEBUGGER_LAST ,0x0258) // The last event from the debugger
+IPC_EVENT_TYPE2(DB_IPCE_DATA_BREAKPOINT_ADD ,0x0258)
+IPC_EVENT_TYPE2(DB_IPCE_DATA_BREAKPOINT_REMOVE ,0x0259)
+IPC_EVENT_TYPE0(DB_IPCE_DEBUGGER_LAST ,0x0260) // The last event from the debugger
};
+[
+ object,
+ local,
+ uuid(CB54E392-C6DD-47BE-9C60-A99F3ECE3A98),
+ pointer_default(unique)
+]
+interface ICorDebugProcess9 : IUnknown
+{
+ HRESULT CreateBreakpoint([in] CORDB_ADDRESS address, [out] ICorDebugValueBreakpoint **ppBreakpoint);
+}
+
#ifdef FEATURE_LEGACYNETCF_DBG_HOST_CONTROL
/* A private API for use on Windows phone to invoke CLR hosting
/* this ALWAYS GENERATED file contains the definitions for the interfaces */
- /* File created by MIDL compiler version 8.00.0603 */
-/* at Fri Sep 23 15:43:16 2016
+ /* File created by MIDL compiler version 8.01.0622 */
+/* at Mon Jan 18 19:14:07 2038
*/
-/* Compiler settings for cordebug.idl:
- Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.00.0603
+/* Compiler settings for C:/coreclr/src/inc/cordebug.idl:
+ Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.01.0622
protocol : dce , ms_ext, c_ext, robust
error checks: allocation ref bounds_check enum stub_data
VC __declspec() decoration level:
#ifndef __RPCNDR_H_VERSION__
#error this stub requires an updated version of <rpcndr.h>
-#endif // __RPCNDR_H_VERSION__
+#endif /* __RPCNDR_H_VERSION__ */
#ifndef COM_NO_WINDOWS_H
#include "windows.h"
#endif /* __ICorDebugProcess8_FWD_DEFINED__ */
+#ifndef __ICorDebugProcess9_FWD_DEFINED__
+#define __ICorDebugProcess9_FWD_DEFINED__
+typedef interface ICorDebugProcess9 ICorDebugProcess9;
+
+#endif /* __ICorDebugProcess9_FWD_DEFINED__ */
+
+
#ifndef __ICorDebugModuleDebugEvent_FWD_DEFINED__
#define __ICorDebugModuleDebugEvent_FWD_DEFINED__
typedef interface ICorDebugModuleDebugEvent ICorDebugModuleDebugEvent;
#endif /* __ICorDebugProcess8_INTERFACE_DEFINED__ */
+#ifndef __ICorDebugProcess9_INTERFACE_DEFINED__
+#define __ICorDebugProcess9_INTERFACE_DEFINED__
+
+/* interface ICorDebugProcess9 */
+/* [unique][uuid][local][object] */
+
+
+EXTERN_C const IID IID_ICorDebugProcess9;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("CB54E392-C6DD-47BE-9C60-A99F3ECE3A98")
+ ICorDebugProcess9 : public IUnknown
+ {
+ public:
+ virtual HRESULT STDMETHODCALLTYPE CreateBreakpoint(
+ /* [in] */ CORDB_ADDRESS address,
+ /* [out] */ ICorDebugValueBreakpoint **ppBreakpoint) = 0;
+
+ };
+
+
+#else /* C style interface */
+
+ typedef struct ICorDebugProcess9Vtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ ICorDebugProcess9 * This,
+ /* [in] */ REFIID riid,
+ /* [annotation][iid_is][out] */
+ _COM_Outptr_ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ ICorDebugProcess9 * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ ICorDebugProcess9 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *CreateBreakpoint )(
+ ICorDebugProcess9 * This,
+ /* [in] */ CORDB_ADDRESS address,
+ /* [out] */ ICorDebugValueBreakpoint **ppBreakpoint);
+
+ END_INTERFACE
+ } ICorDebugProcess9Vtbl;
+
+ interface ICorDebugProcess9
+ {
+ CONST_VTBL struct ICorDebugProcess9Vtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define ICorDebugProcess9_QueryInterface(This,riid,ppvObject) \
+ ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
+
+#define ICorDebugProcess9_AddRef(This) \
+ ( (This)->lpVtbl -> AddRef(This) )
+
+#define ICorDebugProcess9_Release(This) \
+ ( (This)->lpVtbl -> Release(This) )
+
+
+#define ICorDebugProcess9_CreateBreakpoint(This,address,ppBreakpoint) \
+ ( (This)->lpVtbl -> CreateBreakpoint(This,address,ppBreakpoint) )
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+
+#endif /* __ICorDebugProcess9_INTERFACE_DEFINED__ */
+
+
#ifndef __ICorDebugModuleDebugEvent_INTERFACE_DEFINED__
#define __ICorDebugModuleDebugEvent_INTERFACE_DEFINED__
#endif /* __ICorDebugILFrame3_INTERFACE_DEFINED__ */
-/* interface __MIDL_itf_cordebug_0000_0065 */
+/* interface __MIDL_itf_cordebug_0000_0066 */
/* [local] */
typedef
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0065_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0065_v0_0_s_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0066_v0_0_c_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0066_v0_0_s_ifspec;
#ifndef __ICorDebugILFrame4_INTERFACE_DEFINED__
#define __ICorDebugILFrame4_INTERFACE_DEFINED__
#endif /* __ICorDebugNativeFrame_INTERFACE_DEFINED__ */
-/* interface __MIDL_itf_cordebug_0000_0067 */
+/* interface __MIDL_itf_cordebug_0000_0068 */
/* [local] */
#pragma warning(push)
#pragma warning(disable:28718)
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0067_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0067_v0_0_s_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0068_v0_0_c_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0068_v0_0_s_ifspec;
#ifndef __ICorDebugNativeFrame2_INTERFACE_DEFINED__
#define __ICorDebugNativeFrame2_INTERFACE_DEFINED__
#endif /* __ICorDebugModule_INTERFACE_DEFINED__ */
-/* interface __MIDL_itf_cordebug_0000_0071 */
+/* interface __MIDL_itf_cordebug_0000_0072 */
/* [local] */
#pragma warning(pop)
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0071_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0071_v0_0_s_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0072_v0_0_c_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0072_v0_0_s_ifspec;
#ifndef __ICorDebugModule2_INTERFACE_DEFINED__
#define __ICorDebugModule2_INTERFACE_DEFINED__
#endif /* __ICorDebugBoxValue_INTERFACE_DEFINED__ */
-/* interface __MIDL_itf_cordebug_0000_0096 */
+/* interface __MIDL_itf_cordebug_0000_0097 */
/* [local] */
#pragma warning(push)
#pragma warning(disable:28718)
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0096_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0096_v0_0_s_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0097_v0_0_c_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0097_v0_0_s_ifspec;
#ifndef __ICorDebugStringValue_INTERFACE_DEFINED__
#define __ICorDebugStringValue_INTERFACE_DEFINED__
#endif /* __ICorDebugStringValue_INTERFACE_DEFINED__ */
-/* interface __MIDL_itf_cordebug_0000_0097 */
+/* interface __MIDL_itf_cordebug_0000_0098 */
/* [local] */
#pragma warning(pop)
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0097_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0097_v0_0_s_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0098_v0_0_c_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0098_v0_0_s_ifspec;
#ifndef __ICorDebugArrayValue_INTERFACE_DEFINED__
#define __ICorDebugArrayValue_INTERFACE_DEFINED__
#endif /* __ICorDebugBlockingObjectEnum_INTERFACE_DEFINED__ */
-/* interface __MIDL_itf_cordebug_0000_0121 */
+/* interface __MIDL_itf_cordebug_0000_0122 */
/* [local] */
#pragma warning(push)
#pragma warning(disable:28718)
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0121_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0121_v0_0_s_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0122_v0_0_c_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0122_v0_0_s_ifspec;
#ifndef __ICorDebugMDA_INTERFACE_DEFINED__
#define __ICorDebugMDA_INTERFACE_DEFINED__
#endif /* __ICorDebugMDA_INTERFACE_DEFINED__ */
-/* interface __MIDL_itf_cordebug_0000_0122 */
+/* interface __MIDL_itf_cordebug_0000_0123 */
/* [local] */
#pragma warning(pop)
#pragma warning(disable:28718)
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0122_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0122_v0_0_s_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0123_v0_0_c_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0123_v0_0_s_ifspec;
#ifndef __ICorDebugEditAndContinueErrorInfo_INTERFACE_DEFINED__
#define __ICorDebugEditAndContinueErrorInfo_INTERFACE_DEFINED__
#endif /* __ICorDebugEditAndContinueErrorInfo_INTERFACE_DEFINED__ */
-/* interface __MIDL_itf_cordebug_0000_0123 */
+/* interface __MIDL_itf_cordebug_0000_0124 */
/* [local] */
#pragma warning(pop)
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0123_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0123_v0_0_s_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0124_v0_0_c_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0124_v0_0_s_ifspec;
#ifndef __ICorDebugEditAndContinueSnapshot_INTERFACE_DEFINED__
#define __ICorDebugEditAndContinueSnapshot_INTERFACE_DEFINED__
-// 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.
-
/* this ALWAYS GENERATED file contains the definitions for the interfaces */
- /* File created by MIDL compiler version 8.00.0603 */
+ /* File created by MIDL compiler version 8.01.0622 */
+/* at Mon Jan 18 19:14:07 2038
+ */
+/* Compiler settings for C:/coreclr/src/inc/xcordebug.idl:
+ Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.01.0622
+ protocol : dce , ms_ext, c_ext, robust
+ error checks: allocation ref bounds_check enum stub_data
+ VC __declspec() decoration level:
+ __declspec(uuid()), __declspec(selectany), __declspec(novtable)
+ DECLSPEC_UUID(), MIDL_INTERFACE()
+*/
/* @@MIDL_FILE_HEADING( ) */
#pragma warning( disable: 4049 ) /* more than 64k source lines */
#ifndef __RPCNDR_H_VERSION__
#error this stub requires an updated version of <rpcndr.h>
-#endif // __RPCNDR_H_VERSION__
+#endif /* __RPCNDR_H_VERSION__ */
#ifndef COM_NO_WINDOWS_H
#include "windows.h"
#endif /* __ICorDebugProcess4_FWD_DEFINED__ */
+
+#ifndef __ICorDebugProcess9_FWD_DEFINED__
+#define __ICorDebugProcess9_FWD_DEFINED__
+typedef interface ICorDebugProcess9 ICorDebugProcess9;
+
+#endif /* __ICorDebugProcess9_FWD_DEFINED__ */
+
+
#ifndef __ICorDebugLegacyNetCFHostCallbackInvoker_PrivateWindowsPhoneOnly_FWD_DEFINED__
#define __ICorDebugLegacyNetCFHostCallbackInvoker_PrivateWindowsPhoneOnly_FWD_DEFINED__
typedef interface ICorDebugLegacyNetCFHostCallbackInvoker_PrivateWindowsPhoneOnly ICorDebugLegacyNetCFHostCallbackInvoker_PrivateWindowsPhoneOnly;
#endif /* __ICorDebugLegacyNetCFHostCallbackInvoker_PrivateWindowsPhoneOnly_FWD_DEFINED__ */
+
/* header files for imported files */
#include "cordebug.h"
#endif /* __ICorDebugProcess4_INTERFACE_DEFINED__ */
+
+#ifndef __ICorDebugProcess9_INTERFACE_DEFINED__
+#define __ICorDebugProcess9_INTERFACE_DEFINED__
+
+/* interface ICorDebugProcess9 */
+/* [unique][uuid][local][object] */
+
+
+EXTERN_C const IID IID_ICorDebugProcess9;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("CB54E392-C6DD-47BE-9C60-A99F3ECE3A98")
+ ICorDebugProcess9 : public IUnknown
+ {
+ public:
+ virtual HRESULT STDMETHODCALLTYPE CreateBreakpoint(
+ /* [in] */ CORDB_ADDRESS address,
+ /* [out] */ ICorDebugValueBreakpoint **ppBreakpoint) = 0;
+
+ };
+
+
+#else /* C style interface */
+
+ typedef struct ICorDebugProcess9Vtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ ICorDebugProcess9 * This,
+ /* [in] */ REFIID riid,
+ /* [annotation][iid_is][out] */
+ _COM_Outptr_ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ ICorDebugProcess9 * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ ICorDebugProcess9 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *CreateBreakpoint )(
+ ICorDebugProcess9 * This,
+ /* [in] */ CORDB_ADDRESS address,
+ /* [out] */ ICorDebugValueBreakpoint **ppBreakpoint);
+
+ END_INTERFACE
+ } ICorDebugProcess9Vtbl;
+
+ interface ICorDebugProcess9
+ {
+ CONST_VTBL struct ICorDebugProcess9Vtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define ICorDebugProcess9_QueryInterface(This,riid,ppvObject) \
+ ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
+
+#define ICorDebugProcess9_AddRef(This) \
+ ( (This)->lpVtbl -> AddRef(This) )
+
+#define ICorDebugProcess9_Release(This) \
+ ( (This)->lpVtbl -> Release(This) )
+
+
+#define ICorDebugProcess9_CreateBreakpoint(This,address,ppBreakpoint) \
+ ( (This)->lpVtbl -> CreateBreakpoint(This,address,ppBreakpoint) )
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+
+#endif /* __ICorDebugProcess9_INTERFACE_DEFINED__ */
+
+
#ifndef __ICorDebugLegacyNetCFHostCallbackInvoker_PrivateWindowsPhoneOnly_INTERFACE_DEFINED__
#define __ICorDebugLegacyNetCFHostCallbackInvoker_PrivateWindowsPhoneOnly_INTERFACE_DEFINED__
static DWORD LogFlags = 0;
+//static DWORD LogFlags = LOG_ENABLE | LOG_ENABLE_FILE_LOGGING | LOG_ENABLE_DEBUGGER_LOGGING;
static CQuickWSTR szLogFileName;
static HANDLE LogFileHandle = INVALID_HANDLE_VALUE;
static MUTEX_COOKIE LogFileMutex = 0;
static DWORD LogFacilityMask = LF_ALL;
static DWORD LogFacilityMask2 = 0;
-static DWORD LogVMLevel = LL_INFO100;
+static DWORD LogVMLevel = LL_EVERYTHING;
// <TODO>@todo FIX should probably only display warnings and above by default</TODO>