Cosmos/source/Cosmos.VS.DebugEngine/AD7.Impl/AD7BoundBreakpoint.cs
2017-03-19 09:29:46 -05:00

141 lines
5.2 KiB
C#

using System;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Debugger.Interop;
namespace Cosmos.VS.DebugEngine.AD7.Impl
{
// This class represents a breakpoint that has been bound to a location in the debuggee. It is a child of the pending breakpoint
// that creates it. Unless the pending breakpoint only has one bound breakpoint, each bound breakpoint is displayed as a child of the
// pending breakpoint in the breakpoints window. Otherwise, only one is displayed.
public class AD7BoundBreakpoint : IDebugBoundBreakpoint2
{
protected AD7PendingBreakpoint m_pendingBreakpoint;
protected AD7BreakpointResolution m_breakpointResolution;
protected AD7Engine mEngine;
protected bool mEnabled = true;
protected bool mDeleted = false;
public uint mAddress;
protected int mRemoteID = -1;
public int RemoteID
{
get { return mRemoteID; }
}
public AD7BoundBreakpoint(uint aAddress)
{
mEngine = null;
mAddress = aAddress;
m_pendingBreakpoint = null;
m_breakpointResolution = null;
}
public AD7BoundBreakpoint(AD7Engine aEngine, uint aAddress, AD7PendingBreakpoint aPendingBP, AD7BreakpointResolution breakpointResolution)
{
mEngine = aEngine;
mAddress = aAddress;
m_pendingBreakpoint = aPendingBP;
m_breakpointResolution = breakpointResolution;
mRemoteID = mEngine.BPMgr.RemoteEnable(this);
}
// Called when the breakpoint is being deleted by the user.
int IDebugBoundBreakpoint2.Delete()
{
if (!mDeleted)
{
mDeleted = true;
m_pendingBreakpoint.OnBoundBreakpointDeleted(this);
// Remove from DebugStub
mEngine.BPMgr.RemoteDisable(this);
mRemoteID = -1;
}
return VSConstants.S_OK;
}
// Called by the debugger UI when the user is enabling or disabling a breakpoint.
int IDebugBoundBreakpoint2.Enable(int aEnable)
{
bool xEnabled = aEnable != 0;
if (mEnabled != xEnabled)
{
// A production debug engine would remove or add the underlying int3 here. The sample engine does not support true disabling
// of breakpionts.
// Remove from DebugStub
if (xEnabled)
{
mRemoteID = mEngine.BPMgr.RemoteEnable(this);
}
else
{
mEngine.BPMgr.RemoteDisable(this);
}
mEnabled = xEnabled;
}
return VSConstants.S_OK;
}
// Return the breakpoint resolution which describes how the breakpoint bound in the debuggee.
int IDebugBoundBreakpoint2.GetBreakpointResolution(out IDebugBreakpointResolution2 ppBPResolution)
{
ppBPResolution = m_breakpointResolution;
return VSConstants.S_OK;
}
// Return the pending breakpoint for this bound breakpoint.
int IDebugBoundBreakpoint2.GetPendingBreakpoint(out IDebugPendingBreakpoint2 ppPendingBreakpoint)
{
ppPendingBreakpoint = m_pendingBreakpoint;
return VSConstants.S_OK;
}
int IDebugBoundBreakpoint2.GetState(enum_BP_STATE[] state)
{
if (mDeleted)
{
state[0] = enum_BP_STATE.BPS_DELETED;
}
else if (mEnabled)
{
state[0] = enum_BP_STATE.BPS_ENABLED;
}
else
{
state[0] = enum_BP_STATE.BPS_DISABLED;
}
return VSConstants.S_OK;
}
// The sample engine does not support hit counts on breakpoints. A real-world debugger will want to keep track
// of how many times a particular bound breakpoint has been hit and return it here.
int IDebugBoundBreakpoint2.GetHitCount(out uint pdwHitCount)
{
throw new NotImplementedException();
}
// The sample engine does not support conditions on breakpoints.
// A real-world debugger will use this to specify when a breakpoint will be hit
// and when it should be ignored.
int IDebugBoundBreakpoint2.SetCondition(BP_CONDITION bpCondition)
{
throw new NotImplementedException();
}
// The sample engine does not support hit counts on breakpoints. A real-world debugger will want to keep track
// of how many times a particular bound breakpoint has been hit. The debugger calls SetHitCount when the user
// resets a breakpoint's hit count.
int IDebugBoundBreakpoint2.SetHitCount(uint dwHitCount)
{
throw new NotImplementedException();
}
// The sample engine does not support pass counts on breakpoints.
// This is used to specify the breakpoint hit count condition.
int IDebugBoundBreakpoint2.SetPassCount(BP_PASSCOUNT bpPassCount)
{
throw new NotImplementedException();
}
}
}