Cosmos/source2/Debug/Cosmos.Debug.GDB/GDB.cs
kudzu_cp f592992a7d
2010-08-18 05:26:47 +00:00

161 lines
5.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text.RegularExpressions;
using System.Text;
using System.Threading;
namespace Cosmos.Debug.GDB {
public class GDB {
public class Response {
public string Command = "";
public bool Error = false;
public string ErrorMsg = "";
public List<string> Text = new List<string>();
public override string ToString() {
return Command;
}
}
protected System.Diagnostics.Process mGDBProcess;
protected System.IO.StreamReader mGDB;
protected class GDBThread {
protected Thread mThread;
// StreamReader as arg
public GDBThread() {
mThread = new Thread(Execute);
mThread.Start();
}
protected void Execute() {
while (true) {
// ReadLine
Thread.Sleep(1000);
return;
Action<Response> xMethod = OnResponse;
var xResponse = new Response();
// Need to chagne to dispatcher invoke
var xAsync = xMethod.BeginInvoke(xResponse, null, null);
xMethod.EndInvoke(xAsync);
}
}
protected void OnResponse(Response aResponse) {
}
}
static public string Unescape(string aInput) {
// Remove surrounding ", /n, then unescape and trim
string xResult = aInput;
if (xResult.StartsWith("\"")) {
xResult = xResult.Substring(1, aInput.Length - 2);
xResult = xResult.Replace('\n', ' ');
xResult = Regex.Unescape(xResult);
}
return xResult.Trim();
}
protected Response GetResponse() {
var xResult = new Response();
//TODO: Cant find a better way than peek...
while (!mGDBProcess.HasExited) {
var xLine = mGDB.ReadLine();
// Null occurs after quit
if (xLine == null) {
break;
} else if (xLine.Trim() == "(gdb)") {
break;
} else {
var xType = xLine[0];
// & echo of a command
// ~ text response
// ^ done
//&target remote :8832
//&:8832: No connection could be made because the target machine actively refused it.
//^error,msg=":8832: No connection could be made because the target machine actively refused it."
//&target remote :8832
//~Remote debugging using :8832
//~[New Thread 1]
//~0x000ffff0 in ?? ()
//^done
xLine = Unescape(xLine.Substring(1));
if (xType == '&') {
} else if (xType == '^') {
xResult.Error = xLine != "done";
} else if (xType == '~') {
xResult.Text.Add(Unescape(xLine));
}
}
}
return xResult;
}
public Response SendCmd(string aCmd) {
mGDBProcess.StandardInput.WriteLine(aCmd);
var xResult = GetResponse();
xResult.Command = aCmd;
Windows.mLogForm.Log(xResult);
return xResult;
}
protected bool mConnected = false;
public bool Connected {
get { return mConnected; }
}
//TODO: Make path dynamic
protected string mCosmosPath = @"m:\source\Cosmos\";
//static protected string mCosmosPath = @"c:\Data\sources\Cosmos\il2cpu\";
protected GDBThread mThread;
public GDB(int aRetry) {
var xStartInfo = new ProcessStartInfo();
xStartInfo.FileName = mCosmosPath+ @"Build\Tools\gdb.exe";
xStartInfo.Arguments = @"--interpreter=mi2";
xStartInfo.WorkingDirectory = mCosmosPath + @"source2\Users\Kudzu\Breakpoints\bin\debug";
xStartInfo.CreateNoWindow = true;
xStartInfo.UseShellExecute = false;
xStartInfo.RedirectStandardError = true;
xStartInfo.RedirectStandardOutput = true;
xStartInfo.RedirectStandardInput = true;
mGDBProcess = System.Diagnostics.Process.Start(xStartInfo);
mGDB = mGDBProcess.StandardOutput;
mGDBProcess.StandardInput.AutoFlush = true;
mThread = new GDBThread();
GetResponse();
SendCmd("symbol-file Breakpoints.obj");
while (!mConnected) {
var x = SendCmd("target remote :8832");
mConnected = !x.Error;
aRetry--;
if (aRetry == 0) {
return;
}
System.Threading.Thread.Sleep(1000);
System.Windows.Forms.Application.DoEvents();
}
SendCmd("set architecture i386");
SendCmd("set language asm");
SendCmd("set disassembly-flavor intel");
SendCmd("break Kernel_Start");
SendCmd("continue");
SendCmd("delete 1");
}
}
}