Willem Alexander Hajenius <reactos.1000.ahajenius@spamgourmet.com>

- KDBG/IDebugProtocol: parse/add/delete/enable/disable breakpoints. Some other
refactorings done to reduce method size.
- Dockable window that shows current list of breakpoints with add/delete/edit
button (you can also double-click to edit). Breakpoints can easily be
enabled/disabled with a checkbox.
- Dialog window to add or edit breakpoint details. GUI tries to prevent invalid
input.
- Add svn:ignore to RosDBG directory.

svn path=/trunk/reactosdbg/; revision=1308
This commit is contained in:
Aleksey Bragin 2011-08-02 19:54:03 +00:00
parent 520e484253
commit 9868a9e7f5
14 changed files with 1679 additions and 241 deletions

View File

@ -8,19 +8,38 @@ namespace DebugProtocol
public class Breakpoint
{
public enum BPType { Software, Hardware, WriteWatch, ReadWatch, AccessWatch };
public readonly BPType BreakpointType;
public readonly long Address;
public readonly int Length;
public Breakpoint(BPType type, long addr, int len)
public int ID { get; set; }
public BPType BreakpointType { get; set; }
public ulong Address { get; set; }
public int Length { get; set; }
public string Condition { get; set; }
public bool Enabled { get; set; }
public Breakpoint(int id)
{
ID = id;
BreakpointType = BPType.Software;
Address = 0;
Length = 1;
Condition = string.Empty;
Enabled = false;
}
public Breakpoint(int id, BPType type, ulong addr, int len, string cond)
{
ID = id;
BreakpointType = type;
Address = addr;
Length = len;
Condition = cond;
Enabled = false;
}
//TODO: include condition/enabled in hashcode?
public override int GetHashCode()
{
return (int)(((int)BreakpointType) ^ Address ^ (Length << 28));
return (int)(((int)BreakpointType) ^ (int)Address ^ (Length << 28));
}
public override bool Equals(object other)
@ -28,9 +47,10 @@ namespace DebugProtocol
Breakpoint otherbp = other as Breakpoint;
if (otherbp == null) return false;
return
otherbp.ID == ID;/*
(otherbp.BreakpointType == BreakpointType) &&
(otherbp.Address == Address) &&
(otherbp.Length == Length);
(otherbp.Length == Length);*/
}
}
}

View File

@ -42,6 +42,16 @@ namespace DebugProtocol
}
public delegate void DebugRegisterChangeEventHandler(object sender, DebugRegisterChangeEventArgs args);
public class DebugBreakpointChangeEventArgs : EventArgs
{
public readonly IList<Breakpoint> Breakpoints;
public DebugBreakpointChangeEventArgs(IList<Breakpoint> breakpoints)
{
Breakpoints = breakpoints;
}
}
public delegate void DebugBreakpointChangeEventHandler(object sender, DebugBreakpointChangeEventArgs args);
public class DebugRunningChangeEventArgs : EventArgs
{
public readonly bool Running;
@ -180,6 +190,7 @@ namespace DebugProtocol
#endregion
public event DebugRegisterChangeEventHandler DebugRegisterChangeEvent;
public event DebugBreakpointChangeEventHandler DebugBreakpointChangeEvent;
public event DebugConnectedEventHandler DebugConnectionConnectedEvent;
public event DebugConnectionModeChangedEventHandler DebugConnectionModeChangedEvent;
public event DebugRunningChangeEventHandler DebugRunningChangeEvent;
@ -219,6 +230,7 @@ namespace DebugProtocol
{
//set up tab handlers
mKdb.RegisterChangeEvent += RegisterChangeEvent;
mKdb.BreakpointChangeEvent += BreakpointChangeEvent;
mKdb.ModuleListEvent += ModuleListEvent;
mKdb.MemoryUpdateEvent += MemoryUpdateEvent;
mKdb.ProcessListEvent += ProcessListEvent;
@ -292,7 +304,7 @@ namespace DebugProtocol
ConnectEventHandlers();
Running = true;
}
catch (Exception)
catch (Exception ex)
{
ConnectionMode = Mode.ClosedMode;
//error signal?
@ -442,6 +454,12 @@ namespace DebugProtocol
DebugRegisterChangeEvent(this, new DebugRegisterChangeEventArgs(mRegisters));
}
void BreakpointChangeEvent(object sender, BreakpointChangeEventArgs args)
{
if (DebugBreakpointChangeEvent != null)
DebugBreakpointChangeEvent(this, new DebugBreakpointChangeEventArgs(args.Breakpoints));
}
public void Break()
{
if (mKdb != null)

View File

@ -26,6 +26,16 @@ namespace DebugProtocol
}
public delegate void RegisterChangeEventHandler(object sender, RegisterChangeEventArgs args);
public class BreakpointChangeEventArgs : EventArgs
{
public readonly IList<Breakpoint> Breakpoints;
public BreakpointChangeEventArgs(IEnumerable<Breakpoint> breakpoints)
{
Breakpoints = new List<Breakpoint>(breakpoints);
}
}
public delegate void BreakpointChangeEventHandler(object sender, BreakpointChangeEventArgs args);
public class SignalDeliveredEventArgs : EventArgs
{
public readonly int Signal;
@ -96,11 +106,9 @@ namespace DebugProtocol
public interface IDebugProtocol
{
void SetBreakpoint(Breakpoint bp);
void RemoveBreakpoint(Breakpoint bp);
event ConsoleOutputEventHandler ConsoleOutputEvent;
event RegisterChangeEventHandler RegisterChangeEvent;
event BreakpointChangeEventHandler BreakpointChangeEvent;
event SignalDeliveredEventHandler SignalDeliveredEvent;
event RemoteGDBErrorHandler RemoteGDBError;
event MemoryUpdateEventHandler MemoryUpdateEvent;
@ -119,6 +127,12 @@ namespace DebugProtocol
void Break();
void Go(ulong address);
void GetBreakpoints();
void SetBreakpoint(Breakpoint bp);
void RemoveBreakpoint(int id);
void EnableBreakpoint(int id);
void DisableBreakpoint(int id);
void SetProcess(ulong pid);
void SetThread(ulong tid);

View File

@ -7,28 +7,13 @@ using System.Threading;
using System.Globalization;
using AbstractPipe;
using DebugProtocol;
using System.Diagnostics;
namespace KDBGProtocol
{
public class KDBG : IDebugProtocol
{
bool mRunning = true;
Pipe mConnection;
List<string> mCommandBuffer = new List<string>();
Dictionary<string, ulong> mModuleList = new Dictionary<string, ulong>();
ulong []mRegisters = new ulong[32];
public KDBG(Pipe connection)
{
mConnection = connection;
mConnection.PipeReceiveEvent += PipeReceiveEvent;
mConnection.PipeErrorEvent += PipeErrorEvent;
}
void PipeErrorEvent(object sender, PipeErrorEventArgs args)
{
}
#region Regular expressions
static Regex mMemoryRowUpdate = new Regex("<(?<addr>[^>]+)>: (?<row>[0-9a-fA-F? ]*)");
static Regex mModuleOffset = new Regex("(?<modname>[^:]+):(?<offset>[0-9a-fA-f]+).*");
static Regex mModuleUpdate = new Regex("(?<base>[0-9a-fA-F]+) (?<size>[0-9a-fA-F]+) (?<modname>\\w+\\.\\w+)");
@ -43,12 +28,48 @@ namespace KDBGProtocol
static Regex mThreadListHeading = new Regex("TID[ \\t]+State[ \\t]+Prio.*");
static Regex mProcListEntry = new Regex("^(?<cur>([*]|))0x(?<pid>[0-9a-fA-F]+)[ \\t](?<state>[a-zA-Z ]+)[ \\t](?<name>[a-zA-Z. ]+).*");
static Regex mThreadListEntry = new Regex("^(?<cur>([*]|))0x(?<tid>[0-9a-fA-F]+)[ \\t]+(?<state>.*)0x(?<eip>[0-9a-fA-F]*)");
static Regex mBreakpointListEntry = new Regex("^\\*?(?<id>[0-9]{3})[ \\t]+(?<type>BP[X|M])[ \\t]+0x(?<address>[0-9a-fA-F]+)(?<rest>.+)");
#endregion
#region Fields
bool mRunning = true;
Pipe mConnection;
Queue<string> mCommandBuffer = new Queue<string>();
Dictionary<string, ulong> mModuleList = new Dictionary<string, ulong>();
ulong[] mRegisters = new ulong[32];
IList<Breakpoint> mBreakpoints = new List<Breakpoint>();
bool mFirstModuleUpdate = false;
bool mReceivingProcs = false;
bool mReceivingThreads = false;
bool mReceivingBreakpoints = false;
StringBuilder mInputBuffer = new StringBuilder();
int mUsedInput;
#endregion
#region Events
public event ConsoleOutputEventHandler ConsoleOutputEvent;
public event RegisterChangeEventHandler RegisterChangeEvent;
public event BreakpointChangeEventHandler BreakpointChangeEvent;
public event SignalDeliveredEventHandler SignalDeliveredEvent;
public event RemoteGDBErrorHandler RemoteGDBError;
public event MemoryUpdateEventHandler MemoryUpdateEvent;
public event ModuleListEventHandler ModuleListEvent;
public event ProcessListEventHandler ProcessListEvent;
public event ThreadListEventHandler ThreadListEvent;
#endregion
public KDBG(Pipe connection)
{
mConnection = connection;
mConnection.PipeReceiveEvent += PipeReceiveEvent;
mConnection.PipeErrorEvent += PipeErrorEvent;
}
#region Event handlers
void PipeErrorEvent(object sender, PipeErrorEventArgs args)
{
}
void PipeReceiveEvent(object sender, PipeReceiveEventArgs args)
{
@ -102,200 +123,13 @@ namespace KDBGProtocol
mFirstModuleUpdate = true;
}
Match memoryMatch = mMemoryRowUpdate.Match(cleanedLine);
if (memoryMatch.Success)
{
string addrStr = memoryMatch.Groups["addr"].ToString();
Match modOffset = mModuleOffset.Match(addrStr);
ulong updateAddress;
if (modOffset.Success)
{
string modname = modOffset.Groups["modname"].ToString();
ulong offset = ulong.Parse(modOffset.Groups["offset"].ToString(), NumberStyles.HexNumber);
ulong modbase;
if (mModuleList.TryGetValue(modname.ToUpper(), out modbase))
updateAddress = modbase + offset;
else
continue; // Couldn't resolve the address of the named module ...
}
else
{
updateAddress = ulong.Parse(addrStr, NumberStyles.HexNumber);
}
string[] memWords = memoryMatch.Groups["row"].ToString().Split(new char[] { ' ' });
byte []updateBytes = new byte[4 * memWords.Length];
int ctr = 0;
foreach (string word in memWords)
{
if (word[0] == '?')
{
if (MemoryUpdateEvent != null)
MemoryUpdateEvent(this, new MemoryUpdateEventArgs((updateAddress & ~0xfffUL), null));
}
else
{
int wordParsed = int.Parse(word, NumberStyles.HexNumber);
int curCtr = ctr;
for (ctr = curCtr; ctr < curCtr + 4; ctr++)
{
updateBytes[ctr] = (byte)(wordParsed & 0xff);
wordParsed >>= 8;
}
}
}
if (MemoryUpdateEvent != null)
MemoryUpdateEvent(this, new MemoryUpdateEventArgs(updateAddress, updateBytes));
continue;
}
Match moduleMatch = mModuleUpdate.Match(cleanedLine);
if (moduleMatch.Success)
{
ulong baseAddress = ulong.Parse(moduleMatch.Groups["base"].ToString(), NumberStyles.HexNumber);
uint moduleSize = uint.Parse(moduleMatch.Groups["size"].ToString(), NumberStyles.HexNumber);
string moduleName = moduleMatch.Groups["modname"].ToString();
mModuleList[moduleName.ToUpper()] = baseAddress;
if (ModuleListEvent != null)
ModuleListEvent(this, new ModuleListEventArgs(moduleName, baseAddress));
continue;
}
Match csEipMatch = mRegLineCS_EIP.Match(cleanedLine);
if (csEipMatch.Success)
{
uint cs = uint.Parse(csEipMatch.Groups["cs"].ToString(), NumberStyles.HexNumber);
ulong eip = ulong.Parse(csEipMatch.Groups["eip"].ToString(), NumberStyles.HexNumber);
mRegisters[8] = eip;
mRegisters[10] = cs;
continue;
}
Match ssEspMatch = mRegLineSS_ESP.Match(cleanedLine);
if (ssEspMatch.Success)
{
uint ss = uint.Parse(ssEspMatch.Groups["ss"].ToString(), NumberStyles.HexNumber);
ulong esp = ulong.Parse(ssEspMatch.Groups["esp"].ToString(), NumberStyles.HexNumber);
mRegisters[4] = esp;
mRegisters[15] = ss;
continue;
}
Match eaxEbxMatch = mRegLineEAX_EBX.Match(cleanedLine);
if (eaxEbxMatch.Success)
{
ulong eax = ulong.Parse(eaxEbxMatch.Groups["eax"].ToString(), NumberStyles.HexNumber);
ulong ebx = ulong.Parse(eaxEbxMatch.Groups["ebx"].ToString(), NumberStyles.HexNumber);
mRegisters[0] = eax;
mRegisters[3] = ebx;
continue;
}
Match ecxEdxMatch = mRegLineECX_EDX.Match(cleanedLine);
if (ecxEdxMatch.Success)
{
ulong ecx = ulong.Parse(ecxEdxMatch.Groups["ecx"].ToString(), NumberStyles.HexNumber);
ulong edx = ulong.Parse(ecxEdxMatch.Groups["edx"].ToString(), NumberStyles.HexNumber);
mRegisters[1] = ecx;
mRegisters[2] = edx;
continue;
}
Match ebpMatch = mRegLineEBP.Match(cleanedLine);
if (ebpMatch.Success)
{
ulong ebp = ulong.Parse(ebpMatch.Groups["ebp"].ToString(), NumberStyles.HexNumber);
mRegisters[5] = ebp;
continue;
}
Match eflagsMatch = mRegLineEFLAGS.Match(cleanedLine);
if (eflagsMatch.Success)
{
ulong eflags = ulong.Parse(eflagsMatch.Groups["eflags"].ToString(), NumberStyles.HexNumber);
mRegisters[9] = eflags;
if (RegisterChangeEvent != null)
RegisterChangeEvent(this, new RegisterChangeEventArgs(mRegisters));
continue;
}
Match sregMatch = mSregLine.Match(cleanedLine);
if (sregMatch.Success)
{
char []segmap = new char[] { 'C','D','E','F','G','S' };
uint sreg = uint.Parse(sregMatch.Groups["seg"].ToString(), NumberStyles.HexNumber);
int findSeg;
for (findSeg = 0; findSeg < segmap.Length; findSeg++)
{
if (segmap[findSeg] == cleanedLine[0])
{
mRegisters[10 + findSeg] = sreg;
if (segmap[findSeg] == 'S' && RegisterChangeEvent != null)
RegisterChangeEvent(this, new RegisterChangeEventArgs(mRegisters));
break;
}
}
continue;
}
Match pidHeadMatch = mProcListHeading.Match(cleanedLine);
if (pidHeadMatch.Success)
{
mReceivingThreads = false;
mReceivingProcs = true;
if (ProcessListEvent != null)
ProcessListEvent(this, new ProcessListEventArgs());
continue;
}
else
{
Match pidEntryMatch = mProcListEntry.Match(cleanedLine);
if (pidEntryMatch.Success && mReceivingProcs)
{
if (ProcessListEvent != null)
ProcessListEvent(this, new ProcessListEventArgs(ulong.Parse(pidEntryMatch.Groups["pid"].ToString(), NumberStyles.HexNumber), pidEntryMatch.Groups["cur"].Length > 0,
pidEntryMatch.Groups["state"].ToString(), pidEntryMatch.Groups["name"].ToString()));
continue;
}
else
{
if ((mReceivingProcs || cleanedLine.Contains("No processes")) && ProcessListEvent != null)
{
ProcessListEvent(this, new ProcessListEventArgs(true));
mReceivingProcs = false;
continue;
}
}
}
Match tidHeadMatch = mThreadListHeading.Match(cleanedLine);
if (tidHeadMatch.Success)
{
mReceivingThreads = true;
mReceivingProcs = false;
if (ThreadListEvent != null)
ThreadListEvent(this, new ThreadListEventArgs());
continue;
}
else
{
Match tidEntryMatch = mThreadListEntry.Match(cleanedLine);
if (tidEntryMatch.Success && mReceivingThreads)
{
if (ThreadListEvent != null)
ThreadListEvent(this, new ThreadListEventArgs(ulong.Parse(tidEntryMatch.Groups["tid"].ToString(), NumberStyles.HexNumber), tidEntryMatch.Groups["cur"].Length > 0, ulong.Parse(tidEntryMatch.Groups["eip"].ToString(), NumberStyles.HexNumber)));
continue;
}
else
{
if (mReceivingThreads && ThreadListEvent != null)
{
ThreadListEvent(this, new ThreadListEventArgs(true));
mReceivingThreads = false;
continue;
}
}
}
if (TryParseMemory(cleanedLine)) continue;
if (TryParseModule(cleanedLine)) continue;
if (TryParseRegisters(cleanedLine)) continue;
if (TryParseSegmentRegisters(cleanedLine)) continue;
if (TryParsePID(cleanedLine)) continue;
if (TryParseTID(cleanedLine)) continue;
if (TryParseBreakpoint(cleanedLine)) continue;
}
catch (Exception) { /* Error line ... we'll ignore it for now */ }
}
@ -307,40 +141,323 @@ namespace KDBGProtocol
{
if (mCommandBuffer.Count > 0)
{
string firstCommand = mCommandBuffer[0];
mCommandBuffer.RemoveAt(0);
string firstCommand = mCommandBuffer.Dequeue();
mConnection.Write(firstCommand + "\r");
}
}
}
}
#endregion
public void SetBreakpoint(Breakpoint bp)
#region Individual parsing methods, each one looking for a specific item
private bool TryParseMemory(string cleanedLine)
{
Match memoryMatch = mMemoryRowUpdate.Match(cleanedLine);
if (memoryMatch.Success)
{
string addrStr = memoryMatch.Groups["addr"].ToString();
Match modOffset = mModuleOffset.Match(addrStr);
ulong updateAddress;
if (modOffset.Success)
{
string modname = modOffset.Groups["modname"].ToString();
ulong offset = ulong.Parse(modOffset.Groups["offset"].ToString(), NumberStyles.HexNumber);
ulong modbase;
if (mModuleList.TryGetValue(modname.ToUpper(), out modbase))
updateAddress = modbase + offset;
else
return true; // Couldn't resolve the address of the named module ...
}
else
{
updateAddress = ulong.Parse(addrStr, NumberStyles.HexNumber);
}
string[] memWords = memoryMatch.Groups["row"].ToString().Split(new char[] { ' ' });
byte[] updateBytes = new byte[4 * memWords.Length];
int ctr = 0;
foreach (string word in memWords)
{
if (word[0] == '?')
{
if (MemoryUpdateEvent != null)
MemoryUpdateEvent(this, new MemoryUpdateEventArgs((updateAddress & ~0xfffUL), null));
}
else
{
int wordParsed = int.Parse(word, NumberStyles.HexNumber);
int curCtr = ctr;
for (ctr = curCtr; ctr < curCtr + 4; ctr++)
{
updateBytes[ctr] = (byte)(wordParsed & 0xff);
wordParsed >>= 8;
}
}
}
if (MemoryUpdateEvent != null)
MemoryUpdateEvent(this, new MemoryUpdateEventArgs(updateAddress, updateBytes));
return true;
}
return false;
}
public void RemoveBreakpoint(Breakpoint bp)
private bool TryParseModule(string cleanedLine)
{
Match moduleMatch = mModuleUpdate.Match(cleanedLine);
if (moduleMatch.Success)
{
ulong baseAddress = ulong.Parse(moduleMatch.Groups["base"].ToString(), NumberStyles.HexNumber);
uint moduleSize = uint.Parse(moduleMatch.Groups["size"].ToString(), NumberStyles.HexNumber);
string moduleName = moduleMatch.Groups["modname"].ToString();
mModuleList[moduleName.ToUpper()] = baseAddress;
if (ModuleListEvent != null)
ModuleListEvent(this, new ModuleListEventArgs(moduleName, baseAddress));
return true;
}
return false;
}
public event ConsoleOutputEventHandler ConsoleOutputEvent;
public event RegisterChangeEventHandler RegisterChangeEvent;
public event SignalDeliveredEventHandler SignalDeliveredEvent;
public event RemoteGDBErrorHandler RemoteGDBError;
public event MemoryUpdateEventHandler MemoryUpdateEvent;
public event ModuleListEventHandler ModuleListEvent;
public event ProcessListEventHandler ProcessListEvent;
public event ThreadListEventHandler ThreadListEvent;
public void WriteMemory(ulong address, byte[] buf)
private bool TryParseRegisters(string cleanedLine)
{
Match csEipMatch = mRegLineCS_EIP.Match(cleanedLine);
if (csEipMatch.Success)
{
uint cs = uint.Parse(csEipMatch.Groups["cs"].ToString(), NumberStyles.HexNumber);
ulong eip = ulong.Parse(csEipMatch.Groups["eip"].ToString(), NumberStyles.HexNumber);
mRegisters[8] = eip;
mRegisters[10] = cs;
return true;
}
Match ssEspMatch = mRegLineSS_ESP.Match(cleanedLine);
if (ssEspMatch.Success)
{
uint ss = uint.Parse(ssEspMatch.Groups["ss"].ToString(), NumberStyles.HexNumber);
ulong esp = ulong.Parse(ssEspMatch.Groups["esp"].ToString(), NumberStyles.HexNumber);
mRegisters[4] = esp;
mRegisters[15] = ss;
return true;
}
Match eaxEbxMatch = mRegLineEAX_EBX.Match(cleanedLine);
if (eaxEbxMatch.Success)
{
ulong eax = ulong.Parse(eaxEbxMatch.Groups["eax"].ToString(), NumberStyles.HexNumber);
ulong ebx = ulong.Parse(eaxEbxMatch.Groups["ebx"].ToString(), NumberStyles.HexNumber);
mRegisters[0] = eax;
mRegisters[3] = ebx;
return true;
}
Match ecxEdxMatch = mRegLineECX_EDX.Match(cleanedLine);
if (ecxEdxMatch.Success)
{
ulong ecx = ulong.Parse(ecxEdxMatch.Groups["ecx"].ToString(), NumberStyles.HexNumber);
ulong edx = ulong.Parse(ecxEdxMatch.Groups["edx"].ToString(), NumberStyles.HexNumber);
mRegisters[1] = ecx;
mRegisters[2] = edx;
return true;
}
Match ebpMatch = mRegLineEBP.Match(cleanedLine);
if (ebpMatch.Success)
{
ulong ebp = ulong.Parse(ebpMatch.Groups["ebp"].ToString(), NumberStyles.HexNumber);
mRegisters[5] = ebp;
return true;
}
Match eflagsMatch = mRegLineEFLAGS.Match(cleanedLine);
if (eflagsMatch.Success)
{
ulong eflags = ulong.Parse(eflagsMatch.Groups["eflags"].ToString(), NumberStyles.HexNumber);
mRegisters[9] = eflags;
if (RegisterChangeEvent != null)
RegisterChangeEvent(this, new RegisterChangeEventArgs(mRegisters));
return true;
}
return false;
}
private bool TryParseSegmentRegisters(string cleanedLine)
{
Match sregMatch = mSregLine.Match(cleanedLine);
if (sregMatch.Success)
{
char[] segmap = new char[] { 'C', 'D', 'E', 'F', 'G', 'S' };
uint sreg = uint.Parse(sregMatch.Groups["seg"].ToString(), NumberStyles.HexNumber);
int findSeg;
for (findSeg = 0; findSeg < segmap.Length; findSeg++)
{
if (segmap[findSeg] == cleanedLine[0])
{
mRegisters[10 + findSeg] = sreg;
if (segmap[findSeg] == 'S' && RegisterChangeEvent != null)
RegisterChangeEvent(this, new RegisterChangeEventArgs(mRegisters));
break;
}
}
return true;
}
return false;
}
private bool TryParsePID(string cleanedLine)
{
Match pidHeadMatch = mProcListHeading.Match(cleanedLine);
if (pidHeadMatch.Success)
{
mReceivingThreads = false;
mReceivingProcs = true;
if (ProcessListEvent != null)
ProcessListEvent(this, new ProcessListEventArgs());
return true;
}
else
{
Match pidEntryMatch = mProcListEntry.Match(cleanedLine);
if (pidEntryMatch.Success && mReceivingProcs)
{
if (ProcessListEvent != null)
ProcessListEvent(this, new ProcessListEventArgs(ulong.Parse(pidEntryMatch.Groups["pid"].ToString(), NumberStyles.HexNumber), pidEntryMatch.Groups["cur"].Length > 0,
pidEntryMatch.Groups["state"].ToString(), pidEntryMatch.Groups["name"].ToString()));
return true;
}
else
{
if ((mReceivingProcs || cleanedLine.Contains("No processes")) && ProcessListEvent != null)
{
ProcessListEvent(this, new ProcessListEventArgs(true));
mReceivingProcs = false;
return true;
}
}
}
return false;
}
private bool TryParseTID(string cleanedLine)
{
Match tidHeadMatch = mThreadListHeading.Match(cleanedLine);
if (tidHeadMatch.Success)
{
mReceivingThreads = true;
mReceivingProcs = false;
if (ThreadListEvent != null)
ThreadListEvent(this, new ThreadListEventArgs());
return true;
}
else
{
Match tidEntryMatch = mThreadListEntry.Match(cleanedLine);
if (tidEntryMatch.Success && mReceivingThreads)
{
if (ThreadListEvent != null)
ThreadListEvent(this, new ThreadListEventArgs(ulong.Parse(tidEntryMatch.Groups["tid"].ToString(), NumberStyles.HexNumber), tidEntryMatch.Groups["cur"].Length > 0, ulong.Parse(tidEntryMatch.Groups["eip"].ToString(), NumberStyles.HexNumber)));
return true;
}
else
{
if (mReceivingThreads && ThreadListEvent != null)
{
ThreadListEvent(this, new ThreadListEventArgs(true));
mReceivingThreads = false;
return true;
}
}
}
return false;
}
private bool TryParseBreakpoint(string cleanedLine)
{
if (cleanedLine.Equals("Breakpoints:")) // Start looking for breakpoint data
{
mReceivingBreakpoints = true;
return true;
}
else if (cleanedLine.Equals("No breakpoints.")) // Nothing present
{
mReceivingBreakpoints = false;
mBreakpoints.Clear();
if (BreakpointChangeEvent != null)
BreakpointChangeEvent(this, new BreakpointChangeEventArgs(mBreakpoints));
return true;
}
else if (mReceivingBreakpoints)
{
Match breakpointMatch = mBreakpointListEntry.Match(cleanedLine);
if (breakpointMatch.Success)
{
// Process breakpoint data
int id = int.Parse(breakpointMatch.Groups["id"].ToString(), NumberStyles.Integer);
Breakpoint bp = new Breakpoint(id);
string type = breakpointMatch.Groups["type"].ToString();
bp.Address = ulong.Parse(breakpointMatch.Groups["address"].ToString(), NumberStyles.HexNumber);
bp.Enabled = true;
bp.Condition = string.Empty;
string rest = breakpointMatch.Groups["rest"].ToString();
int cond_start = rest.LastIndexOf("IF");
if (cond_start >= 0) // Separate the condition from the other properties
{
bp.Condition = rest.Substring(cond_start + 2).Trim();
rest = rest.Substring(0, cond_start);
}
string[] properties = rest.Split(' ');
foreach (string property in properties)
{
if (type.Equals("BPM"))
{
if (property.Equals("read"))
bp.BreakpointType = Breakpoint.BPType.ReadWatch;
else if (property.Equals("write"))
bp.BreakpointType = Breakpoint.BPType.WriteWatch;
else if (property.Equals("rdwr"))
bp.BreakpointType = Breakpoint.BPType.AccessWatch;
else if (property.Equals("exec"))
bp.BreakpointType = Breakpoint.BPType.Hardware;
else if (property.Equals("byte"))
bp.Length = 1;
else if (property.Equals("word"))
bp.Length = 2;
else if (property.Equals("dword"))
bp.Length = 4;
}
else if (type.Equals("BPX"))
{
bp.BreakpointType = Breakpoint.BPType.Software;
}
// Common properties
if (property.Equals("disabled"))
bp.Enabled = false;
}
mBreakpoints.Add(bp);
return true;
}
else // Something else; it implies that we've got all the breakpoint data
{
if (BreakpointChangeEvent != null)
BreakpointChangeEvent(this, new BreakpointChangeEventArgs(mBreakpoints));
mBreakpoints.Clear();
mReceivingBreakpoints = false;
return false;
}
}
return false;
}
#endregion
#region Upstream commands
public void QueueCommand(string command)
{
lock (mCommandBuffer)
{
mCommandBuffer.Add(command);
mCommandBuffer.Enqueue(command);
}
}
@ -357,7 +474,9 @@ namespace KDBGProtocol
{
}
/* Immediately executed commands */
#endregion
#region Immediately executed commands
public void Step()
{
Write("step");
@ -389,12 +508,77 @@ namespace KDBGProtocol
mFirstModuleUpdate = false;
}
public void GetBreakpoints()
{
Write("bl");
}
public void SetBreakpoint(Breakpoint bp)
{
string length = "byte";
if (bp.Length == 2) length = "word";
else if (bp.Length == 4) length = "dword";
StringBuilder command = new StringBuilder();
switch (bp.BreakpointType)
{
case Breakpoint.BPType.Software:
command.AppendFormat("bpx 0x{0:x8}", bp.Address);
break;
case Breakpoint.BPType.Hardware:
command.AppendFormat("bpm x {0} 0x{1:x8}", "byte", bp.Address);
break;
case Breakpoint.BPType.ReadWatch:
command.AppendFormat("bpm r {0} 0x{1:x8}", length, bp.Address);
break;
case Breakpoint.BPType.WriteWatch:
command.AppendFormat("bpm w {0} 0x{1:x8}", length, bp.Address);
break;
case Breakpoint.BPType.AccessWatch:
command.AppendFormat("bpm rw {0} 0x{1:x8}", length, bp.Address);
break;
}
if (!string.IsNullOrEmpty(bp.Condition))
command.AppendFormat(" IF {0}", bp.Condition);
Write(command.ToString());
GetBreakpoints();
}
public void RemoveBreakpoint(int id)
{
if (id >= 0)
Write("bc " + id);
GetBreakpoints();
}
public void EnableBreakpoint(int id)
{
if (id >= 0)
Write("be " + id);
GetBreakpoints();
}
public void DisableBreakpoint(int id)
{
if (id >= 0)
Write("bd " + id);
GetBreakpoints();
}
public void WriteMemory(ulong address, byte[] buf)
{
}
public void GetMemoryUpdate(ulong address, int len)
{
Write(string.Format("x 0x{0:X} L {1}", address, len));
}
#endregion
/* Commands placed into the cmd queue */
#region Commands placed into the command queue
public void GetProcesses()
{
QueueCommand("proc list");
@ -428,5 +612,7 @@ namespace KDBGProtocol
{
QueueCommand("mod");
}
#endregion
}
}

View File

@ -0,0 +1,200 @@
namespace RosDBG
{
partial class BreakpointWindow
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle3 = new System.Windows.Forms.DataGridViewCellStyle();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(BreakpointWindow));
this.grid = new System.Windows.Forms.DataGridView();
this.columnEnabled = new System.Windows.Forms.DataGridViewCheckBoxColumn();
this.columnID = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.columnAddress = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.columnType = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.columnCondition = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.breakpointBindingSource = new System.Windows.Forms.BindingSource(this.components);
this.btnAddBreakpoint = new System.Windows.Forms.Button();
this.btnDeleteBreakpoint = new System.Windows.Forms.Button();
this.btnEditBreakpoint = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.grid)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.breakpointBindingSource)).BeginInit();
this.SuspendLayout();
//
// grid
//
this.grid.AllowUserToAddRows = false;
this.grid.AllowUserToDeleteRows = false;
this.grid.AllowUserToResizeRows = false;
this.grid.AutoGenerateColumns = false;
this.grid.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader;
this.grid.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.grid.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.columnEnabled,
this.columnID,
this.columnAddress,
this.columnType,
this.columnCondition});
this.grid.DataSource = this.breakpointBindingSource;
this.grid.Dock = System.Windows.Forms.DockStyle.Top;
this.grid.Location = new System.Drawing.Point(0, 0);
this.grid.MultiSelect = false;
this.grid.Name = "grid";
this.grid.RowHeadersVisible = false;
this.grid.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
this.grid.Size = new System.Drawing.Size(318, 228);
this.grid.StandardTab = true;
this.grid.TabIndex = 1;
this.grid.CellDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.grid_CellDoubleClick);
this.grid.CellFormatting += new System.Windows.Forms.DataGridViewCellFormattingEventHandler(this.grid_CellFormatting);
this.grid.CellValueChanged += new System.Windows.Forms.DataGridViewCellEventHandler(this.grid_CellValueChanged);
this.grid.CurrentCellDirtyStateChanged += new System.EventHandler(this.grid_CurrentCellDirtyStateChanged);
//
// columnEnabled
//
this.columnEnabled.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCellsExceptHeader;
this.columnEnabled.DataPropertyName = "Enabled";
this.columnEnabled.HeaderText = "";
this.columnEnabled.Name = "columnEnabled";
this.columnEnabled.Width = 5;
//
// columnID
//
this.columnID.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCellsExceptHeader;
this.columnID.DataPropertyName = "ID";
dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleRight;
this.columnID.DefaultCellStyle = dataGridViewCellStyle1;
this.columnID.HeaderText = "ID";
this.columnID.Name = "columnID";
this.columnID.ReadOnly = true;
this.columnID.Width = 5;
//
// columnAddress
//
this.columnAddress.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells;
this.columnAddress.DataPropertyName = "Address";
dataGridViewCellStyle2.Format = "X8";
this.columnAddress.DefaultCellStyle = dataGridViewCellStyle2;
this.columnAddress.HeaderText = "Address";
this.columnAddress.Name = "columnAddress";
this.columnAddress.ReadOnly = true;
this.columnAddress.Width = 70;
//
// columnType
//
this.columnType.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells;
this.columnType.DataPropertyName = "BreakpointType";
dataGridViewCellStyle3.NullValue = null;
this.columnType.DefaultCellStyle = dataGridViewCellStyle3;
this.columnType.HeaderText = "Type";
this.columnType.Name = "columnType";
this.columnType.ReadOnly = true;
this.columnType.Width = 56;
//
// columnCondition
//
this.columnCondition.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells;
this.columnCondition.DataPropertyName = "Condition";
this.columnCondition.HeaderText = "Condition";
this.columnCondition.Name = "columnCondition";
this.columnCondition.ReadOnly = true;
this.columnCondition.Width = 76;
//
// breakpointBindingSource
//
this.breakpointBindingSource.DataSource = typeof(DebugProtocol.Breakpoint);
//
// btnAddBreakpoint
//
this.btnAddBreakpoint.Enabled = false;
this.btnAddBreakpoint.Location = new System.Drawing.Point(12, 234);
this.btnAddBreakpoint.Name = "btnAddBreakpoint";
this.btnAddBreakpoint.Size = new System.Drawing.Size(48, 23);
this.btnAddBreakpoint.TabIndex = 2;
this.btnAddBreakpoint.Text = "&Add...";
this.btnAddBreakpoint.UseVisualStyleBackColor = true;
this.btnAddBreakpoint.Click += new System.EventHandler(this.btnAddBreakpoint_Click);
//
// btnDeleteBreakpoint
//
this.btnDeleteBreakpoint.Enabled = false;
this.btnDeleteBreakpoint.Location = new System.Drawing.Point(66, 234);
this.btnDeleteBreakpoint.Name = "btnDeleteBreakpoint";
this.btnDeleteBreakpoint.Size = new System.Drawing.Size(48, 23);
this.btnDeleteBreakpoint.TabIndex = 4;
this.btnDeleteBreakpoint.Text = "&Delete";
this.btnDeleteBreakpoint.UseVisualStyleBackColor = true;
this.btnDeleteBreakpoint.Click += new System.EventHandler(this.btnDelete_Click);
//
// btnEditBreakpoint
//
this.btnEditBreakpoint.Enabled = false;
this.btnEditBreakpoint.Location = new System.Drawing.Point(120, 234);
this.btnEditBreakpoint.Name = "btnEditBreakpoint";
this.btnEditBreakpoint.Size = new System.Drawing.Size(48, 23);
this.btnEditBreakpoint.TabIndex = 5;
this.btnEditBreakpoint.Text = "&Edit...";
this.btnEditBreakpoint.UseVisualStyleBackColor = true;
this.btnEditBreakpoint.Click += new System.EventHandler(this.btnEdit_Click);
//
// BreakpointWindow
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(318, 262);
this.Controls.Add(this.btnEditBreakpoint);
this.Controls.Add(this.btnDeleteBreakpoint);
this.Controls.Add(this.btnAddBreakpoint);
this.Controls.Add(this.grid);
this.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.HideOnClose = true;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Name = "BreakpointWindow";
this.Text = "Breakpoints";
((System.ComponentModel.ISupportInitialize)(this.grid)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.breakpointBindingSource)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.DataGridView grid;
private System.Windows.Forms.Button btnAddBreakpoint;
private System.Windows.Forms.BindingSource breakpointBindingSource;
private System.Windows.Forms.Button btnDeleteBreakpoint;
private System.Windows.Forms.Button btnEditBreakpoint;
private System.Windows.Forms.DataGridViewCheckBoxColumn columnEnabled;
private System.Windows.Forms.DataGridViewTextBoxColumn columnID;
private System.Windows.Forms.DataGridViewTextBoxColumn columnAddress;
private System.Windows.Forms.DataGridViewTextBoxColumn columnType;
private System.Windows.Forms.DataGridViewTextBoxColumn columnCondition;
}
}

View File

@ -0,0 +1,193 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Globalization;
using System.Threading;
using DebugProtocol;
using WeifenLuo.WinFormsUI.Docking;
namespace RosDBG
{
[DebugControl]
public partial class BreakpointWindow : ToolWindow, IUseDebugConnection
{
DebugConnection mConnection;
bool mRunning = true;
ulong last_EIP;
IList<Breakpoint> mBreakpoints;
public BreakpointWindow()
{
InitializeComponent();
grid.DataSource = mBreakpoints;
}
public void SetDebugConnection(DebugConnection conn)
{
mConnection = conn;
conn.DebugRunningChangeEvent += DebugRunningChangeEvent;
conn.DebugRegisterChangeEvent += new DebugRegisterChangeEventHandler(DebugRegisterChangeEvent);
conn.DebugBreakpointChangeEvent += new DebugBreakpointChangeEventHandler(DebugBreakpointChangeEvent);
mRunning = conn.Running;
if (!mConnection.Running)
mConnection.Debugger.GetBreakpoints();
}
#region Debugger events
void DebugRegisterChangeEvent(object sender, DebugRegisterChangeEventArgs args)
{
last_EIP = args.Registers.Eip;
}
void DebugBreakpointChangeEvent(object sender, DebugBreakpointChangeEventArgs args)
{
mBreakpoints = args.Breakpoints;
RefreshView();
}
void DebugRunningChangeEvent(object sender, DebugRunningChangeEventArgs args)
{
this.UIThread(delegate
{
mRunning = args.Running;
grid.Enabled = !mRunning;
btnAddBreakpoint.Enabled = !mRunning;
btnDeleteBreakpoint.Enabled = !mRunning;
btnEditBreakpoint.Enabled = !mRunning;
});
}
#endregion
#region Utility methods
private void RefreshView()
{
this.UIThread(delegate
{
if (!mRunning)
{
// Track selected row
DataGridViewSelectedRowCollection sel_rows = grid.SelectedRows;
int sel_row = (sel_rows.Count >= 1 ? sel_rows[0].Index : 0);
grid.DataSource = null;
grid.DataSource = mBreakpoints;
grid.Refresh();
// Restore selected row, if possible
if (sel_row < grid.RowCount) grid.Rows[sel_row].Selected = true;
}
});
}
private string GetLengthString(int length)
{
switch (length)
{
case 1: return "byte";
case 2: return "word";
case 4: return "dword";
default: return "";
}
}
private void EditBreakpoint(Breakpoint storedBreakpoint)
{
using (EditBreakpointDialog dialog = new EditBreakpointDialog(storedBreakpoint))
{
dialog.ShowDialog();
if (dialog.DialogResult == DialogResult.OK && dialog.Breakpoint != null)
{
Breakpoint bp = dialog.Breakpoint;
if (storedBreakpoint.ID >= 0)
mConnection.Debugger.RemoveBreakpoint(storedBreakpoint.ID);
mConnection.Debugger.SetBreakpoint(bp);
}
}
}
#endregion
#region User interface event handlers
// See the note in the Remarks section at the MSDN entry for DataGridViewCheckboxColumn
private void grid_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (grid.CurrentCell is DataGridViewCheckBoxCell)
{
grid.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
}
private void grid_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex >= 0 && e.RowIndex < grid.Rows.Count && e.ColumnIndex == this.columnEnabled.Index)
{
DataGridViewCheckBoxCell cell = grid[e.ColumnIndex, e.RowIndex] as DataGridViewCheckBoxCell;
if (cell != null && !mConnection.Running)
{
Breakpoint bp = grid.Rows[e.RowIndex].DataBoundItem as Breakpoint;
if ((bool)cell.Value)
mConnection.Debugger.EnableBreakpoint(bp.ID);
else
mConnection.Debugger.DisableBreakpoint(bp.ID);
}
}
}
private void grid_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex >= 0 && e.RowIndex < grid.Rows.Count && e.RowIndex < mBreakpoints.Count)
{
Breakpoint storedBreakpoint = mBreakpoints[e.RowIndex];
EditBreakpoint(storedBreakpoint);
}
}
private void grid_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
Breakpoint bp = grid.Rows[e.RowIndex].DataBoundItem as Breakpoint;
if (e.ColumnIndex == columnType.Index)
{
switch (bp.BreakpointType)
{
case Breakpoint.BPType.Software: e.Value = "execute"; break;
case Breakpoint.BPType.Hardware: e.Value = "exec " + GetLengthString(bp.Length); break;
case Breakpoint.BPType.ReadWatch: e.Value = "read " +GetLengthString(bp.Length); break;
case Breakpoint.BPType.WriteWatch: e.Value = "write " + GetLengthString(bp.Length); break;
case Breakpoint.BPType.AccessWatch: e.Value = "r/w " + GetLengthString(bp.Length); break;
default: e.Value = "?"; break;
}
}
}
private void btnAddBreakpoint_Click(object sender, EventArgs e)
{
Breakpoint orig_bp = new Breakpoint(-1, Breakpoint.BPType.Software, last_EIP, 1, "");
EditBreakpoint(orig_bp);
}
private void btnDelete_Click(object sender, EventArgs e)
{
if (grid.SelectedRows.Count >= 1)
{
Breakpoint bp = grid.SelectedRows[0].DataBoundItem as Breakpoint;
mConnection.Debugger.RemoveBreakpoint(bp.ID);
}
}
private void btnEdit_Click(object sender, EventArgs e)
{
if (grid.SelectedRows.Count >= 1)
{
Breakpoint storedBreakpoint = grid.SelectedRows[0].DataBoundItem as Breakpoint;
EditBreakpoint(storedBreakpoint);
}
}
#endregion
}
}

View File

@ -0,0 +1,152 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="breakpointBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAAEAEBAAAAAAAABoBQAAFgAAACgAAAAQAAAAIAAAAAEACAAAAAAAQAEAAAAAAAAAAAAAAAAAAAAA
AAAAAAAA////AISKiADDyscAoKOiAOzu7gC0urgAz9fTAJOZlwC+wMAAio+NALm/vQCHi4kAhYqIAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANDQ0AAAAAAAAAAAAADQ0A
DQUNAA0NAAAAAAAADQUJDQQHBA0JBQ0AAAAAAA0JBwcHBwcHBwkNAAAAAAAADQUGCggCAwcNAAAAAAAN
DQQHCgAAAAIHBA0NAAAADQUHBwgAAAAIBwcFDQAAAA0NBAcCAAAADAcEDQ0AAAAAAA0HBgIIAgsHDQAA
AAAAAA0JBwcHBwcHBwkNAAAAAAANBQkNBAcEDQkFDQAAAAAAAA0NAA0FDQANDQAAAAAAAAAAAAANDQ0A
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AAD//wAA/H8AAORPAADABwAAwAcAAOAPAACDgwAAg4MAAIOD
AADgDwAAwAcAAMAHAADkTwAA/H8AAP//AAA=
</value>
</data>
</root>

331
RosDBG/EditBreakpointDialog.Designer.cs generated Normal file
View File

@ -0,0 +1,331 @@
namespace RosDBG
{
partial class EditBreakpointDialog
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
this.txtCondition = new System.Windows.Forms.TextBox();
this.label2 = new System.Windows.Forms.Label();
this.txtAddress = new System.Windows.Forms.TextBox();
this.gbxScope = new System.Windows.Forms.GroupBox();
this.radDword = new System.Windows.Forms.RadioButton();
this.radWord = new System.Windows.Forms.RadioButton();
this.radByte = new System.Windows.Forms.RadioButton();
this.gbxTrigger = new System.Windows.Forms.GroupBox();
this.radExecute = new System.Windows.Forms.RadioButton();
this.radReadWrite = new System.Windows.Forms.RadioButton();
this.radWrite = new System.Windows.Forms.RadioButton();
this.radRead = new System.Windows.Forms.RadioButton();
this.label1 = new System.Windows.Forms.Label();
this.gbxType = new System.Windows.Forms.GroupBox();
this.radBPM = new System.Windows.Forms.RadioButton();
this.radBPX = new System.Windows.Forms.RadioButton();
this.btnOK = new System.Windows.Forms.Button();
this.btnCancel = new System.Windows.Forms.Button();
this.splitContainer1.Panel1.SuspendLayout();
this.splitContainer1.Panel2.SuspendLayout();
this.splitContainer1.SuspendLayout();
this.gbxScope.SuspendLayout();
this.gbxTrigger.SuspendLayout();
this.gbxType.SuspendLayout();
this.SuspendLayout();
//
// splitContainer1
//
this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
this.splitContainer1.FixedPanel = System.Windows.Forms.FixedPanel.Panel2;
this.splitContainer1.IsSplitterFixed = true;
this.splitContainer1.Location = new System.Drawing.Point(0, 0);
this.splitContainer1.Name = "splitContainer1";
this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal;
//
// splitContainer1.Panel1
//
this.splitContainer1.Panel1.Controls.Add(this.txtCondition);
this.splitContainer1.Panel1.Controls.Add(this.label2);
this.splitContainer1.Panel1.Controls.Add(this.txtAddress);
this.splitContainer1.Panel1.Controls.Add(this.gbxScope);
this.splitContainer1.Panel1.Controls.Add(this.gbxTrigger);
this.splitContainer1.Panel1.Controls.Add(this.label1);
this.splitContainer1.Panel1.Controls.Add(this.gbxType);
//
// splitContainer1.Panel2
//
this.splitContainer1.Panel2.Controls.Add(this.btnOK);
this.splitContainer1.Panel2.Controls.Add(this.btnCancel);
this.splitContainer1.Size = new System.Drawing.Size(330, 200);
this.splitContainer1.SplitterDistance = 167;
this.splitContainer1.TabIndex = 0;
//
// txtCondition
//
this.txtCondition.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.txtCondition.Location = new System.Drawing.Point(82, 135);
this.txtCondition.Margin = new System.Windows.Forms.Padding(3, 3, 6, 3);
this.txtCondition.Name = "txtCondition";
this.txtCondition.Size = new System.Drawing.Size(239, 20);
this.txtCondition.TabIndex = 5;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(18, 138);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(54, 13);
this.label2.TabIndex = 7;
this.label2.Text = "Condition:";
//
// txtAddress
//
this.txtAddress.Location = new System.Drawing.Point(81, 99);
this.txtAddress.Margin = new System.Windows.Forms.Padding(3, 3, 6, 3);
this.txtAddress.MaxLength = 8;
this.txtAddress.Name = "txtAddress";
this.txtAddress.Size = new System.Drawing.Size(58, 20);
this.txtAddress.TabIndex = 1;
this.txtAddress.Validating += new System.ComponentModel.CancelEventHandler(this.txtAddress_Validating);
//
// gbxScope
//
this.gbxScope.Controls.Add(this.radDword);
this.gbxScope.Controls.Add(this.radWord);
this.gbxScope.Controls.Add(this.radByte);
this.gbxScope.Location = new System.Drawing.Point(251, 12);
this.gbxScope.Name = "gbxScope";
this.gbxScope.Size = new System.Drawing.Size(70, 117);
this.gbxScope.TabIndex = 4;
this.gbxScope.TabStop = false;
this.gbxScope.Text = "Scope";
//
// radDword
//
this.radDword.AutoSize = true;
this.radDword.Location = new System.Drawing.Point(6, 65);
this.radDword.Name = "radDword";
this.radDword.Size = new System.Drawing.Size(59, 17);
this.radDword.TabIndex = 2;
this.radDword.Text = "DWord";
this.radDword.UseVisualStyleBackColor = true;
//
// radWord
//
this.radWord.AutoSize = true;
this.radWord.Location = new System.Drawing.Point(6, 42);
this.radWord.Name = "radWord";
this.radWord.Size = new System.Drawing.Size(51, 17);
this.radWord.TabIndex = 1;
this.radWord.Text = "Word";
this.radWord.UseVisualStyleBackColor = true;
//
// radByte
//
this.radByte.AutoSize = true;
this.radByte.Checked = true;
this.radByte.Location = new System.Drawing.Point(6, 19);
this.radByte.Name = "radByte";
this.radByte.Size = new System.Drawing.Size(46, 17);
this.radByte.TabIndex = 0;
this.radByte.TabStop = true;
this.radByte.Text = "Byte";
this.radByte.UseVisualStyleBackColor = true;
//
// gbxTrigger
//
this.gbxTrigger.Controls.Add(this.radExecute);
this.gbxTrigger.Controls.Add(this.radReadWrite);
this.gbxTrigger.Controls.Add(this.radWrite);
this.gbxTrigger.Controls.Add(this.radRead);
this.gbxTrigger.Location = new System.Drawing.Point(148, 12);
this.gbxTrigger.Name = "gbxTrigger";
this.gbxTrigger.Size = new System.Drawing.Size(97, 117);
this.gbxTrigger.TabIndex = 3;
this.gbxTrigger.TabStop = false;
this.gbxTrigger.Text = "Trigger";
//
// radExecute
//
this.radExecute.AutoSize = true;
this.radExecute.Location = new System.Drawing.Point(6, 88);
this.radExecute.Name = "radExecute";
this.radExecute.Size = new System.Drawing.Size(72, 17);
this.radExecute.TabIndex = 3;
this.radExecute.Text = "Execution";
this.radExecute.UseVisualStyleBackColor = true;
//
// radReadWrite
//
this.radReadWrite.AutoSize = true;
this.radReadWrite.Location = new System.Drawing.Point(6, 65);
this.radReadWrite.Name = "radReadWrite";
this.radReadWrite.Size = new System.Drawing.Size(81, 17);
this.radReadWrite.TabIndex = 2;
this.radReadWrite.Text = "Read/Write";
this.radReadWrite.UseVisualStyleBackColor = true;
//
// radWrite
//
this.radWrite.AutoSize = true;
this.radWrite.Location = new System.Drawing.Point(6, 42);
this.radWrite.Name = "radWrite";
this.radWrite.Size = new System.Drawing.Size(50, 17);
this.radWrite.TabIndex = 1;
this.radWrite.Text = "Write";
this.radWrite.UseVisualStyleBackColor = true;
//
// radRead
//
this.radRead.AutoSize = true;
this.radRead.Checked = true;
this.radRead.Location = new System.Drawing.Point(6, 19);
this.radRead.Name = "radRead";
this.radRead.Size = new System.Drawing.Size(51, 17);
this.radRead.TabIndex = 0;
this.radRead.TabStop = true;
this.radRead.Text = "Read";
this.radRead.UseVisualStyleBackColor = true;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(18, 102);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(48, 13);
this.label1.TabIndex = 9;
this.label1.Text = "Address:";
//
// gbxType
//
this.gbxType.Controls.Add(this.radBPM);
this.gbxType.Controls.Add(this.radBPX);
this.gbxType.Location = new System.Drawing.Point(12, 12);
this.gbxType.Name = "gbxType";
this.gbxType.Size = new System.Drawing.Size(130, 73);
this.gbxType.TabIndex = 2;
this.gbxType.TabStop = false;
this.gbxType.Text = "Type";
//
// radBPM
//
this.radBPM.AutoSize = true;
this.radBPM.Location = new System.Drawing.Point(9, 44);
this.radBPM.Name = "radBPM";
this.radBPM.Size = new System.Drawing.Size(103, 17);
this.radBPM.TabIndex = 1;
this.radBPM.Text = "Hardware (BPM)";
this.radBPM.UseVisualStyleBackColor = true;
//
// radBPX
//
this.radBPX.AutoSize = true;
this.radBPX.Checked = true;
this.radBPX.Location = new System.Drawing.Point(9, 21);
this.radBPX.Name = "radBPX";
this.radBPX.Size = new System.Drawing.Size(97, 17);
this.radBPX.TabIndex = 0;
this.radBPX.TabStop = true;
this.radBPX.Text = "Software (BPX)";
this.radBPX.UseVisualStyleBackColor = true;
//
// btnOK
//
this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnOK.Location = new System.Drawing.Point(171, 3);
this.btnOK.Name = "btnOK";
this.btnOK.Size = new System.Drawing.Size(75, 23);
this.btnOK.TabIndex = 6;
this.btnOK.Text = "OK";
this.btnOK.UseVisualStyleBackColor = true;
this.btnOK.Click += new System.EventHandler(this.btnOK_Click);
//
// btnCancel
//
this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.btnCancel.Location = new System.Drawing.Point(252, 3);
this.btnCancel.Name = "btnCancel";
this.btnCancel.Size = new System.Drawing.Size(75, 23);
this.btnCancel.TabIndex = 7;
this.btnCancel.Text = "Cancel";
this.btnCancel.UseVisualStyleBackColor = true;
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
//
// EditBreakpoint
//
this.AcceptButton = this.btnOK;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.btnCancel;
this.ClientSize = new System.Drawing.Size(330, 200);
this.Controls.Add(this.splitContainer1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "EditBreakpoint";
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Add or edit breakpoint";
this.Activated += new System.EventHandler(this.EditBreakpoint_Activated);
this.splitContainer1.Panel1.ResumeLayout(false);
this.splitContainer1.Panel1.PerformLayout();
this.splitContainer1.Panel2.ResumeLayout(false);
this.splitContainer1.ResumeLayout(false);
this.gbxScope.ResumeLayout(false);
this.gbxScope.PerformLayout();
this.gbxTrigger.ResumeLayout(false);
this.gbxTrigger.PerformLayout();
this.gbxType.ResumeLayout(false);
this.gbxType.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.SplitContainer splitContainer1;
private System.Windows.Forms.Button btnOK;
private System.Windows.Forms.Button btnCancel;
private System.Windows.Forms.TextBox txtAddress;
private System.Windows.Forms.GroupBox gbxScope;
private System.Windows.Forms.RadioButton radDword;
private System.Windows.Forms.RadioButton radWord;
private System.Windows.Forms.RadioButton radByte;
private System.Windows.Forms.GroupBox gbxTrigger;
private System.Windows.Forms.RadioButton radExecute;
private System.Windows.Forms.RadioButton radReadWrite;
private System.Windows.Forms.RadioButton radWrite;
private System.Windows.Forms.RadioButton radRead;
private System.Windows.Forms.GroupBox gbxType;
private System.Windows.Forms.RadioButton radBPM;
private System.Windows.Forms.RadioButton radBPX;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox txtCondition;
}
}

View File

@ -0,0 +1,179 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Windows.Forms;
using System.Drawing.Design;
using System.IO;
using System.IO.Ports;
using System.Globalization;
using DebugProtocol;
namespace RosDBG
{
/// <summary>
/// Use this form as a dialog to edit beakpoint data. DialogResult will be OK or Cancel;
/// if OK, you can get the chosen data from the Breakpoint property.
/// </summary>
public partial class EditBreakpointDialog : Form
{
/// <summary>
/// Chosen breakpoint data if OK pressed, or null if Cancel pressed
/// </summary>
public Breakpoint Breakpoint { get; private set; }
/// <summary>
/// Constructor
/// </summary>
/// <param name="breakpoint">Breakpoint data to prefill in the form (skipped if null)</param>
public EditBreakpointDialog(Breakpoint breakpoint)
{
InitializeComponent();
Breakpoint = breakpoint;
radBPX.CheckedChanged += new EventHandler(radioButtonChanged);
radBPM.CheckedChanged += new EventHandler(radioButtonChanged);
radByte.CheckedChanged += new EventHandler(radioButtonChanged);
radWord.CheckedChanged += new EventHandler(radioButtonChanged);
radDword.CheckedChanged += new EventHandler(radioButtonChanged);
radRead.CheckedChanged += new EventHandler(radioButtonChanged);
radWrite.CheckedChanged += new EventHandler(radioButtonChanged);
radReadWrite.CheckedChanged += new EventHandler(radioButtonChanged);
radExecute.CheckedChanged += new EventHandler(radioButtonChanged);
// Prefill the form with the data from the given breakpoint
if (breakpoint != null)
{
switch (breakpoint.BreakpointType)
{
case DebugProtocol.Breakpoint.BPType.Software:
radBPX.Select();
break;
case DebugProtocol.Breakpoint.BPType.Hardware:
radBPM.Select();
radExecute.Select();
break;
case DebugProtocol.Breakpoint.BPType.ReadWatch:
radBPM.Select();
radRead.Select();
break;
case DebugProtocol.Breakpoint.BPType.WriteWatch:
radBPM.Select();
radWrite.Select();
break;
case DebugProtocol.Breakpoint.BPType.AccessWatch:
radBPM.Select();
radReadWrite.Select();
break;
}
if (breakpoint.BreakpointType != DebugProtocol.Breakpoint.BPType.Software)
{
switch (breakpoint.Length)
{
case 1: radByte.Select(); break;
case 2: radWord.Select(); break;
case 4: radDword.Select(); break;
}
}
txtAddress.Text = breakpoint.Address.ToString("X8");
txtCondition.Text = breakpoint.Condition;
}
}
#region Event handlers
private void EditBreakpoint_Activated(object sender, EventArgs e)
{
ValidateForm();
txtAddress.Focus();
txtAddress.SelectAll();
}
private void radioButtonChanged(object sender, EventArgs e)
{
RadioButton rb = sender as RadioButton;
if (rb != null && rb.Checked)
ValidateForm();
}
private void btnCancel_Click(object sender, EventArgs e)
{
Breakpoint = null;
DialogResult = DialogResult.Cancel;
Close();
}
private void btnOK_Click(object sender, EventArgs e)
{
try
{
if (Breakpoint == null)
Breakpoint = new Breakpoint(-1);
Breakpoint.Enabled = false;
Breakpoint.Address = ulong.Parse(txtAddress.Text, NumberStyles.HexNumber);
Breakpoint.Condition = txtCondition.Text;
if (radBPX.Checked)
{
Breakpoint.BreakpointType = DebugProtocol.Breakpoint.BPType.Software;
Breakpoint.Length = 1;
}
else if (radBPM.Checked)
{
if (radRead.Checked)
Breakpoint.BreakpointType = DebugProtocol.Breakpoint.BPType.ReadWatch;
else if (radWrite.Checked)
Breakpoint.BreakpointType = DebugProtocol.Breakpoint.BPType.WriteWatch;
else if (radReadWrite.Checked)
Breakpoint.BreakpointType = DebugProtocol.Breakpoint.BPType.AccessWatch;
else if (radExecute.Checked)
Breakpoint.BreakpointType = DebugProtocol.Breakpoint.BPType.Hardware;
if (radByte.Checked) Breakpoint.Length = 1;
else if (radWord.Checked) Breakpoint.Length = 2;
else if (radDword.Checked) Breakpoint.Length = 4;
}
DialogResult = DialogResult.OK;
Close();
}
catch (Exception) { } // If something goes wrong, don't close
}
private void txtAddress_Validating(object sender, CancelEventArgs e)
{
ulong answer;
if (ulong.TryParse(txtAddress.Text, NumberStyles.HexNumber, null, out answer))
{
e.Cancel = false;
txtAddress.BackColor = SystemColors.Window;
}
else
{
e.Cancel = true;
txtAddress.BackColor = Color.Yellow;
}
}
#endregion
#region Utility methods
private void ValidateForm()
{
bool addressFocused = txtAddress.Focused;
gbxScope.Enabled = radBPM.Checked;
gbxTrigger.Enabled = radBPM.Checked;
if (radExecute.Checked) radByte.Select();
if (addressFocused) txtAddress.Focus();
}
#endregion
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -28,7 +28,8 @@ namespace RosDBG
private Locals m_Locals = new Locals();
private MemoryWindow m_MemoryWindow = new MemoryWindow();
private ProcThread m_ProcThread = new ProcThread();
private Modules m_Modules = new Modules();
private Modules m_Modules = new Modules();
private BreakpointWindow m_Breakpoints = new BreakpointWindow();
private bool mRunning;
private DebugConnection.Mode mConnectionMode;
@ -60,9 +61,12 @@ namespace RosDBG
RegisterControl(m_MemoryWindow);
RegisterControl(m_ProcThread);
RegisterControl(m_Modules);
RegisterControl(m_Breakpoints);
m_Locals.Show(dockPanel, DockState.DockRight);
m_RegView.Show(dockPanel, DockState.DockRight);
m_Breakpoints.Show(dockPanel, DockState.DockRight);
m_RegView.Activate();
m_BackTrace.Show(dockPanel, DockState.DockBottom);
m_RawTraffic.Show(dockPanel);
m_Modules.Show(dockPanel);

View File

@ -39,5 +39,5 @@ using System.Runtime.InteropServices;
// will be increased as well. MSI installers must not be generated with the same Build Number
// otherwise they won't upgrade the old installation!
[assembly: AssemblyVersion("1.0.23.7")]
[assembly: AssemblyFileVersion("1.0.23.7")]
[assembly: AssemblyVersion("1.0.23.10")]
[assembly: AssemblyFileVersion("1.0.23.10")]

View File

View File

@ -106,6 +106,12 @@
<DependentUpon>Connect.cs</DependentUpon>
</Compile>
<Compile Include="ControlExtensions.cs" />
<Compile Include="EditBreakpointDialog.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="EditBreakpointDialog.Designer.cs">
<DependentUpon>EditBreakpointDialog.cs</DependentUpon>
</Compile>
<Compile Include="Diagnostics.cs" />
<Compile Include="Dockable Objects\BackTrace.cs">
<SubType>Form</SubType>
@ -117,6 +123,12 @@
<SubType>Code</SubType>
</Compile>
<Compile Include="DebugInfoFile.cs" />
<Compile Include="Dockable Objects\BreakpointWindow.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Dockable Objects\BreakpointWindow.Designer.cs">
<DependentUpon>BreakpointWindow.cs</DependentUpon>
</Compile>
<Compile Include="Dockable Objects\StatefulRegisterView.cs">
<SubType>Form</SubType>
</Compile>
@ -185,10 +197,18 @@
<DependentUpon>Connect.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="EditBreakpointDialog.resx">
<DependentUpon>EditBreakpointDialog.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Dockable Objects\BackTrace.resx">
<DependentUpon>BackTrace.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Dockable Objects\BreakpointWindow.resx">
<DependentUpon>BreakpointWindow.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Dockable Objects\Locals.resx">
<DependentUpon>Locals.cs</DependentUpon>
<SubType>Designer</SubType>
@ -246,6 +266,7 @@
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<None Include="Properties\DataSources\DebugProtocol.Breakpoint.datasource" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>