mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-27 05:52:11 +00:00
Debugger pipe work.
This commit is contained in:
parent
b69139311e
commit
733d3de69b
4 changed files with 149 additions and 144 deletions
|
|
@ -86,7 +86,7 @@ Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "Docs", "..\Docs", "{67E7DEF
|
||||||
Release.AspNetCompiler.ForceOverwrite = "true"
|
Release.AspNetCompiler.ForceOverwrite = "true"
|
||||||
Release.AspNetCompiler.FixedNames = "false"
|
Release.AspNetCompiler.FixedNames = "false"
|
||||||
Release.AspNetCompiler.Debug = "False"
|
Release.AspNetCompiler.Debug = "False"
|
||||||
VWDPort = "6281"
|
VWDPort = "28453"
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cosmos.Debug.Consts", "..\source2\IL2CPU\Cosmos.IL2CPU.Debug\Cosmos.Debug.Consts.csproj", "{9998B4EA-385E-4DA2-8905-2BBEB5B2C6E2}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cosmos.Debug.Consts", "..\source2\IL2CPU\Cosmos.IL2CPU.Debug\Cosmos.Debug.Consts.csproj", "{9998B4EA-385E-4DA2-8905-2BBEB5B2C6E2}"
|
||||||
|
|
|
||||||
|
|
@ -125,25 +125,29 @@ namespace Cosmos.Debug.Common
|
||||||
SendCommand(DsCmd.SendStack);
|
SendCommand(DsCmd.SendStack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Ping() {
|
||||||
|
SendCommand(DsCmd.Ping);
|
||||||
|
}
|
||||||
|
|
||||||
public void SetBreakpoint(int aID, uint aAddress) {
|
public void SetBreakpoint(int aID, uint aAddress) {
|
||||||
// Not needed as SendCommand will do it, but it saves
|
// Not needed as SendCommand will do it, but it saves
|
||||||
// some execution, but more importantly stops it from
|
// some execution, but more importantly stops it from
|
||||||
// logging messages to debug output for events that
|
// logging messages to debug output for events that
|
||||||
// dont happen.
|
// dont happen.
|
||||||
if (!Connected) {
|
if (!Connected) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aAddress == 0) {
|
if (aAddress == 0) {
|
||||||
DoDebugMsg("DS Cmd: BP " + aID + " deleted");
|
DoDebugMsg("DS Cmd: BP " + aID + " deleted");
|
||||||
} else {
|
} else {
|
||||||
DoDebugMsg("DS Cmd: BP " + aID + " @ " + aAddress.ToString("X8").ToUpper());
|
DoDebugMsg("DS Cmd: BP " + aID + " @ " + aAddress.ToString("X8").ToUpper());
|
||||||
}
|
}
|
||||||
|
|
||||||
var xData = new byte[5];
|
var xData = new byte[5];
|
||||||
Array.Copy(BitConverter.GetBytes(aAddress), 0, xData, 0, 4);
|
Array.Copy(BitConverter.GetBytes(aAddress), 0, xData, 0, 4);
|
||||||
xData[4] = (byte)aID;
|
xData[4] = (byte)aID;
|
||||||
SendCommandData(DsCmd.BreakOnAddress, xData, true);
|
SendCommandData(DsCmd.BreakOnAddress, xData, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] GetMemoryData(uint address, uint size, int dataElementSize = 1)
|
public byte[] GetMemoryData(uint address, uint size, int dataElementSize = 1)
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ namespace Cosmos.Debug.Common {
|
||||||
// We need to delay creation and connect until its used, so we guarantee
|
// We need to delay creation and connect until its used, so we guarantee
|
||||||
// that the server side is active and ready.
|
// that the server side is active and ready.
|
||||||
if (mPipe == null) {
|
if (mPipe == null) {
|
||||||
mPipe = new NamedPipeClientStream(".", Cosmos.Debug.Consts.Pipes.DownName, PipeDirection.Out);
|
mPipe = new NamedPipeClientStream(".", mPipeName, PipeDirection.Out);
|
||||||
try {
|
try {
|
||||||
// For now we assume its there or not from the first call.
|
// For now we assume its there or not from the first call.
|
||||||
// If we don't find the server, we disable it to avoid causing lag.
|
// If we don't find the server, we disable it to avoid causing lag.
|
||||||
|
|
@ -42,11 +42,11 @@ namespace Cosmos.Debug.Common {
|
||||||
if (xData == null) {
|
if (xData == null) {
|
||||||
xData = new byte[0];
|
xData = new byte[0];
|
||||||
}
|
}
|
||||||
int xLength = Math.Min(aData.Length, 32768);
|
int xLength = Math.Min(xData.Length, 32768);
|
||||||
mPipe.WriteByte((byte)(xLength >> 8));
|
mPipe.WriteByte((byte)(xLength >> 8));
|
||||||
mPipe.WriteByte((byte)(xLength & 0xFF));
|
mPipe.WriteByte((byte)(xLength & 0xFF));
|
||||||
if (xLength > 0) {
|
if (xLength > 0) {
|
||||||
mPipe.Write(aData, 0, xLength);
|
mPipe.Write(xData, 0, xLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
mPipe.Flush();
|
mPipe.Flush();
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,6 @@ namespace Cosmos.Debug.VSDebugEngine {
|
||||||
if (String.IsNullOrEmpty(xVmwarePath) || !File.Exists(xVmwarePath)) {
|
if (String.IsNullOrEmpty(xVmwarePath) || !File.Exists(xVmwarePath)) {
|
||||||
MessageBox.Show("VWMare is not installed, probably going to crash now!", "Cosmos DebugEngine", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
MessageBox.Show("VWMare is not installed, probably going to crash now!", "Cosmos DebugEngine", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetVMWareWorkstationPath() {
|
private static string GetVMWareWorkstationPath() {
|
||||||
|
|
@ -134,150 +133,152 @@ namespace Cosmos.Debug.VSDebugEngine {
|
||||||
mDebugDownPipe.SendCommand(DwMsg.Registers, aData);
|
mDebugDownPipe.SendCommand(DwMsg.Registers, aData);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void DbgCmdFrame(byte[] aData)
|
protected void DbgCmdFrame(byte[] aData) {
|
||||||
{
|
|
||||||
mDebugDownPipe.SendCommand(DwMsg.Frame, aData);
|
mDebugDownPipe.SendCommand(DwMsg.Frame, aData);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void DbgCmdStack(byte[] aData)
|
protected void DbgCmdStack(byte[] aData) {
|
||||||
{
|
|
||||||
mDebugDownPipe.SendCommand(DwMsg.Stack, aData);
|
mDebugDownPipe.SendCommand(DwMsg.Stack, aData);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal AD7Process(NameValueCollection aDebugInfo, EngineCallback aCallback, AD7Engine aEngine, IDebugPort2 aPort)
|
void mDebugUpPipe_DataPacketReceived(byte arg1, byte[] arg2) {
|
||||||
{
|
}
|
||||||
System.Diagnostics.Debug.WriteLine("In AD7Process..ctor");
|
|
||||||
mCallback = aCallback;
|
|
||||||
|
|
||||||
// Load passed in values
|
internal AD7Process(NameValueCollection aDebugInfo, EngineCallback aCallback, AD7Engine aEngine, IDebugPort2 aPort) {
|
||||||
mDebugInfo = aDebugInfo;
|
System.Diagnostics.Debug.WriteLine("In AD7Process..ctor");
|
||||||
|
mCallback = aCallback;
|
||||||
|
|
||||||
mDebugDownPipe = new Cosmos.Debug.Common.PipeClient(Cosmos.Debug.Consts.Pipes.DownName);
|
// Load passed in values
|
||||||
mDebugUpPipe = new Cosmos.Debug.Common.PipeServer(Cosmos.Debug.Consts.Pipes.UpName);
|
mDebugInfo = aDebugInfo;
|
||||||
|
|
||||||
mISO = mDebugInfo["ISOFile"];
|
mDebugDownPipe = new Cosmos.Debug.Common.PipeClient(Cosmos.Debug.Consts.Pipes.DownName);
|
||||||
mProjectFile = mDebugInfo["ProjectFile"];
|
mDebugUpPipe = new Cosmos.Debug.Common.PipeServer(Cosmos.Debug.Consts.Pipes.UpName);
|
||||||
//
|
mDebugUpPipe.DataPacketReceived += new Action<byte, byte[]>(mDebugUpPipe_DataPacketReceived);
|
||||||
var xGDBDebugStub = false;
|
mDebugUpPipe.Start();
|
||||||
Boolean.TryParse(mDebugInfo["EnableGDB"], out xGDBDebugStub);
|
|
||||||
//
|
|
||||||
var xGDBClient = false;
|
|
||||||
Boolean.TryParse(mDebugInfo["StartCosmosGDB"], out xGDBClient);
|
|
||||||
|
|
||||||
mProcessStartInfo = new ProcessStartInfo(Path.Combine(PathUtilities.GetVSIPDir(), "Cosmos.Debug.HostProcess.exe"));
|
mISO = mDebugInfo["ISOFile"];
|
||||||
if (StringComparer.InvariantCultureIgnoreCase.Equals(mDebugInfo["BuildTarget"], "VMWare"))
|
mProjectFile = mDebugInfo["ProjectFile"];
|
||||||
{
|
//
|
||||||
mTargetHost = TargetHost.VMWare;
|
var xGDBDebugStub = false;
|
||||||
if (StringComparer.InvariantCultureIgnoreCase.Equals(mDebugInfo["VMWareFlavor"], "Player"))
|
Boolean.TryParse(mDebugInfo["EnableGDB"], out xGDBDebugStub);
|
||||||
{
|
//
|
||||||
mVMWareFlavor = VMwareFlavor.Player;
|
var xGDBClient = false;
|
||||||
}
|
Boolean.TryParse(mDebugInfo["StartCosmosGDB"], out xGDBClient);
|
||||||
else if (StringComparer.InvariantCultureIgnoreCase.Equals(mDebugInfo["VMWareFlavor"], "Workstation"))
|
|
||||||
{
|
|
||||||
mVMWareFlavor = VMwareFlavor.Workstation;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new Exception("VMWare Flavor '" + mDebugInfo["VMWareFlavor"] + "' not implemented!");
|
|
||||||
}
|
|
||||||
LaunchVMWare(xGDBDebugStub);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new Exception("Invalid BuildTarget value: '" + mDebugInfo["BuildTarget"] + "'!");
|
|
||||||
}
|
|
||||||
|
|
||||||
mProcessStartInfo.UseShellExecute = false;
|
mProcessStartInfo = new ProcessStartInfo(Path.Combine(PathUtilities.GetVSIPDir(), "Cosmos.Debug.HostProcess.exe"));
|
||||||
mProcessStartInfo.RedirectStandardInput = true;
|
if (StringComparer.InvariantCultureIgnoreCase.Equals(mDebugInfo["BuildTarget"], "VMWare"))
|
||||||
mProcessStartInfo.RedirectStandardError = true;
|
{
|
||||||
mProcessStartInfo.RedirectStandardOutput = true;
|
mTargetHost = TargetHost.VMWare;
|
||||||
mProcessStartInfo.CreateNoWindow = true;
|
if (StringComparer.InvariantCultureIgnoreCase.Equals(mDebugInfo["VMWareFlavor"], "Player"))
|
||||||
|
{
|
||||||
|
mVMWareFlavor = VMwareFlavor.Player;
|
||||||
|
}
|
||||||
|
else if (StringComparer.InvariantCultureIgnoreCase.Equals(mDebugInfo["VMWareFlavor"], "Workstation"))
|
||||||
|
{
|
||||||
|
mVMWareFlavor = VMwareFlavor.Workstation;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new Exception("VMWare Flavor '" + mDebugInfo["VMWareFlavor"] + "' not implemented!");
|
||||||
|
}
|
||||||
|
LaunchVMWare(xGDBDebugStub);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new Exception("Invalid BuildTarget value: '" + mDebugInfo["BuildTarget"] + "'!");
|
||||||
|
}
|
||||||
|
|
||||||
string xCpdbPath = Path.ChangeExtension(mISO, "cpdb");
|
mProcessStartInfo.UseShellExecute = false;
|
||||||
if (!File.Exists(xCpdbPath))
|
mProcessStartInfo.RedirectStandardInput = true;
|
||||||
{
|
mProcessStartInfo.RedirectStandardError = true;
|
||||||
throw new Exception("Debug data file " + xCpdbPath + " not found! Could be a omitted build process of Cosmos project so that not created.");
|
mProcessStartInfo.RedirectStandardOutput = true;
|
||||||
}
|
mProcessStartInfo.CreateNoWindow = true;
|
||||||
|
|
||||||
mDebugInfoDb = new DebugInfo();
|
string xCpdbPath = Path.ChangeExtension(mISO, "cpdb");
|
||||||
mDebugInfoDb.OpenCPDB(xCpdbPath);
|
if (!File.Exists(xCpdbPath))
|
||||||
mDebugInfoDb.ReadLabels(out mAddressLabelMappings, out mLabelAddressMappings);
|
{
|
||||||
if (mAddressLabelMappings.Count == 0)
|
throw new Exception("Debug data file " + xCpdbPath + " not found! Could be a omitted build process of Cosmos project so that not created.");
|
||||||
{
|
}
|
||||||
throw new Exception("Debug data not found: LabelByAddressMapping");
|
|
||||||
}
|
|
||||||
|
|
||||||
mSourceMappings = Cosmos.Debug.Common.SourceInfo.GetSourceInfo(mAddressLabelMappings, mLabelAddressMappings, mDebugInfoDb);
|
mDebugInfoDb = new DebugInfo();
|
||||||
|
mDebugInfoDb.OpenCPDB(xCpdbPath);
|
||||||
|
mDebugInfoDb.ReadLabels(out mAddressLabelMappings, out mLabelAddressMappings);
|
||||||
|
if (mAddressLabelMappings.Count == 0)
|
||||||
|
{
|
||||||
|
throw new Exception("Debug data not found: LabelByAddressMapping");
|
||||||
|
}
|
||||||
|
|
||||||
if (mSourceMappings.Count == 0)
|
mSourceMappings = Cosmos.Debug.Common.SourceInfo.GetSourceInfo(mAddressLabelMappings, mLabelAddressMappings, mDebugInfoDb);
|
||||||
{
|
|
||||||
throw new Exception("Debug data not found: SourceMappings");
|
|
||||||
}
|
|
||||||
mReverseSourceMappings = new ReverseSourceInfos(mSourceMappings);
|
|
||||||
if (StringComparer.InvariantCultureIgnoreCase.Equals(mDebugInfo["BuildTarget"], "vmware"))
|
|
||||||
{
|
|
||||||
mDbgConnector = new Cosmos.Debug.Common.DebugConnectorPipeServer();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new Exception("BuildTarget value not valid: '" + mDebugInfo["BuildTarget"] + "'!");
|
|
||||||
}
|
|
||||||
aEngine.BPMgr.SetDebugConnector(mDbgConnector);
|
|
||||||
|
|
||||||
mDbgConnector.CmdTrace += new Action<byte, uint>(DbgCmdTrace);
|
if (mSourceMappings.Count == 0)
|
||||||
mDbgConnector.CmdText += new Action<string>(DbgCmdText);
|
{
|
||||||
mDbgConnector.CmdStarted += new Action(DbgCmdStarted);
|
throw new Exception("Debug data not found: SourceMappings");
|
||||||
mDbgConnector.OnDebugMsg += new Action<string>(DebugMsg);
|
}
|
||||||
mDbgConnector.ConnectionLost += new Action<Exception>(DbgConnector_ConnectionLost);
|
mReverseSourceMappings = new ReverseSourceInfos(mSourceMappings);
|
||||||
mDbgConnector.CmdRegisters += new Action<byte[]>(DbgCmdRegisters);
|
if (StringComparer.InvariantCultureIgnoreCase.Equals(mDebugInfo["BuildTarget"], "vmware"))
|
||||||
mDbgConnector.CmdFrame += new Action<byte[]>(DbgCmdFrame);
|
{
|
||||||
mDbgConnector.CmdStack += new Action<byte[]>(DbgCmdStack);
|
mDbgConnector = new Cosmos.Debug.Common.DebugConnectorPipeServer();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new Exception("BuildTarget value not valid: '" + mDebugInfo["BuildTarget"] + "'!");
|
||||||
|
}
|
||||||
|
aEngine.BPMgr.SetDebugConnector(mDbgConnector);
|
||||||
|
|
||||||
System.Threading.Thread.Sleep(250);
|
mDbgConnector.CmdTrace += new Action<byte, uint>(DbgCmdTrace);
|
||||||
System.Diagnostics.Debug.WriteLine(String.Format("Launching process: \"{0}\" {1}", mProcessStartInfo.FileName, mProcessStartInfo.Arguments).Trim());
|
mDbgConnector.CmdText += new Action<string>(DbgCmdText);
|
||||||
mProcess = Process.Start(mProcessStartInfo);
|
mDbgConnector.CmdStarted += new Action(DbgCmdStarted);
|
||||||
|
mDbgConnector.OnDebugMsg += new Action<string>(DebugMsg);
|
||||||
|
mDbgConnector.ConnectionLost += new Action<Exception>(DbgConnector_ConnectionLost);
|
||||||
|
mDbgConnector.CmdRegisters += new Action<byte[]>(DbgCmdRegisters);
|
||||||
|
mDbgConnector.CmdFrame += new Action<byte[]>(DbgCmdFrame);
|
||||||
|
mDbgConnector.CmdStack += new Action<byte[]>(DbgCmdStack);
|
||||||
|
|
||||||
mProcess.EnableRaisingEvents = true;
|
System.Threading.Thread.Sleep(250);
|
||||||
mProcess.Exited += new EventHandler(mProcess_Exited);
|
System.Diagnostics.Debug.WriteLine(String.Format("Launching process: \"{0}\" {1}", mProcessStartInfo.FileName, mProcessStartInfo.Arguments).Trim());
|
||||||
|
mProcess = Process.Start(mProcessStartInfo);
|
||||||
|
|
||||||
// Sleep 250 and see if it exited too quickly. Why do we do this? We have .Exited hooked. Is this in case it happens between start and hook?
|
mProcess.EnableRaisingEvents = true;
|
||||||
// if so, why not hook before start?
|
mProcess.Exited += new EventHandler(mProcess_Exited);
|
||||||
// MtW: we do this for the potential situation where it might exit before the Exited event is hooked. Iirc i had this situation before..
|
|
||||||
System.Threading.Thread.Sleep(250);
|
|
||||||
if (mProcess.HasExited)
|
|
||||||
{
|
|
||||||
Trace.WriteLine("Error while running: " + mProcess.StandardError.ReadToEnd());
|
|
||||||
Trace.WriteLine(mProcess.StandardOutput.ReadToEnd());
|
|
||||||
Trace.WriteLine("ExitCode: " + mProcess.ExitCode);
|
|
||||||
throw new Exception("Error while starting application");
|
|
||||||
}
|
|
||||||
|
|
||||||
mEngine = aEngine;
|
// Sleep 250 and see if it exited too quickly. Why do we do this? We have .Exited hooked. Is this in case it happens between start and hook?
|
||||||
mThread = new AD7Thread(aEngine, this);
|
// if so, why not hook before start?
|
||||||
mCallback.OnThreadStart(mThread);
|
// MtW: we do this for the potential situation where it might exit before the Exited event is hooked. Iirc i had this situation before..
|
||||||
mPort = aPort;
|
System.Threading.Thread.Sleep(250);
|
||||||
|
if (mProcess.HasExited)
|
||||||
|
{
|
||||||
|
Trace.WriteLine("Error while running: " + mProcess.StandardError.ReadToEnd());
|
||||||
|
Trace.WriteLine(mProcess.StandardOutput.ReadToEnd());
|
||||||
|
Trace.WriteLine("ExitCode: " + mProcess.ExitCode);
|
||||||
|
throw new Exception("Error while starting application");
|
||||||
|
}
|
||||||
|
|
||||||
// Launch GDB Client
|
mEngine = aEngine;
|
||||||
if (xGDBDebugStub && xGDBClient)
|
mThread = new AD7Thread(aEngine, this);
|
||||||
{
|
mCallback.OnThreadStart(mThread);
|
||||||
if (File.Exists(Cosmos.Build.Common.CosmosPaths.GDBClientExe))
|
mPort = aPort;
|
||||||
{
|
|
||||||
var xPSInfo = new ProcessStartInfo(Cosmos.Build.Common.CosmosPaths.GDBClientExe);
|
// Launch GDB Client
|
||||||
xPSInfo.Arguments = "\"" + Path.ChangeExtension(mProjectFile, ".cgdb") + "\"" + @" /Connect";
|
if (xGDBDebugStub && xGDBClient)
|
||||||
xPSInfo.UseShellExecute = false;
|
{
|
||||||
xPSInfo.RedirectStandardInput = false;
|
if (File.Exists(Cosmos.Build.Common.CosmosPaths.GDBClientExe))
|
||||||
xPSInfo.RedirectStandardError = false;
|
{
|
||||||
xPSInfo.RedirectStandardOutput = false;
|
var xPSInfo = new ProcessStartInfo(Cosmos.Build.Common.CosmosPaths.GDBClientExe);
|
||||||
xPSInfo.CreateNoWindow = false;
|
xPSInfo.Arguments = "\"" + Path.ChangeExtension(mProjectFile, ".cgdb") + "\"" + @" /Connect";
|
||||||
Process.Start(xPSInfo);
|
xPSInfo.UseShellExecute = false;
|
||||||
}
|
xPSInfo.RedirectStandardInput = false;
|
||||||
else
|
xPSInfo.RedirectStandardError = false;
|
||||||
{
|
xPSInfo.RedirectStandardOutput = false;
|
||||||
MessageBox.Show(string.Format(
|
xPSInfo.CreateNoWindow = false;
|
||||||
"The GDB-Client could not be found at \"{0}\". Please deactivate it under \"Properties/Debug/Enable GDB\"",
|
Process.Start(xPSInfo);
|
||||||
Cosmos.Build.Common.CosmosPaths.GDBClientExe), "GDB-Client", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);
|
}
|
||||||
}
|
else
|
||||||
}
|
{
|
||||||
|
MessageBox.Show(string.Format(
|
||||||
|
"The GDB-Client could not be found at \"{0}\". Please deactivate it under \"Properties/Debug/Enable GDB\"",
|
||||||
|
Cosmos.Build.Common.CosmosPaths.GDBClientExe), "GDB-Client", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DbgConnector_ConnectionLost(Exception e) {
|
private void DbgConnector_ConnectionLost(Exception e) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue