mirror of
https://github.com/reactos/reactosdbg.git
synced 2024-11-23 03:39:43 +00:00
518 lines
19 KiB
C#
518 lines
19 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Data;
|
|
using System.Drawing;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Windows.Forms;
|
|
using System.Reflection;
|
|
using System.Diagnostics;
|
|
using WeifenLuo.WinFormsUI.Docking;
|
|
using AbstractPipe;
|
|
using DebugProtocol;
|
|
using KDBGProtocol;
|
|
using DbgHelpAPI;
|
|
|
|
namespace RosDBG
|
|
{
|
|
public delegate void NoParamsDelegate();
|
|
|
|
public partial class MainWindow : Form, IShell
|
|
{
|
|
//private RegisterView m_RegView = new RegisterView();
|
|
private StatefulRegisterView m_RegView = new StatefulRegisterView();
|
|
private BackTrace m_BackTrace = new BackTrace();
|
|
private RawTraffic m_RawTraffic = new RawTraffic();
|
|
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 BreakpointWindow m_Breakpoints = new BreakpointWindow();
|
|
|
|
private bool mRunning;
|
|
private DebugConnection.Mode mConnectionMode;
|
|
private ulong mCurrentEip;
|
|
private string mSourceRoot = Settings.SourceDirectory, mCurrentFile;
|
|
private int mCurrentLine;
|
|
private DebugConnection mConnection = new DebugConnection();
|
|
private SymbolContext mSymbolContext;
|
|
Dictionary<uint, Module> mModules = new Dictionary<uint, Module>();
|
|
private Dictionary<string, SourceView> mSourceFiles = new Dictionary<string, SourceView>();
|
|
|
|
//public event CopyEventHandler CopyEvent;
|
|
|
|
public MainWindow()
|
|
{
|
|
InitializeComponent();
|
|
|
|
// Setup the logger
|
|
RosDiagnostics.SetupLogger();
|
|
|
|
RosDiagnostics.DebugTrace(RosDiagnostics.TraceType.Info, "Initialising application");
|
|
|
|
mSymbolContext = new SymbolContext();
|
|
|
|
RegisterControl(m_RegView);
|
|
RegisterControl(m_BackTrace);
|
|
RegisterControl(m_RawTraffic);
|
|
RegisterControl(m_Locals);
|
|
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);
|
|
m_ProcThread.Show(dockPanel);
|
|
ReactOSWeb web = new ReactOSWeb();
|
|
web.Show(dockPanel);
|
|
}
|
|
|
|
void ComposeTitleString()
|
|
{
|
|
FocusAddress(mCurrentEip);
|
|
|
|
string mode;
|
|
switch (mConnectionMode)
|
|
{
|
|
case DebugConnection.Mode.ClosedMode: mode = "Closed"; break;
|
|
case DebugConnection.Mode.PipeMode: mode = "Pipe"; break;
|
|
case DebugConnection.Mode.SerialMode: mode = "Serial"; break;
|
|
case DebugConnection.Mode.SocketMode: mode = "Socket"; break;
|
|
default: mode = "Unknown"; break;
|
|
}
|
|
|
|
toolStripStatusConnectionMode.Text = mode;
|
|
if (mConnectionMode == DebugConnection.Mode.ClosedMode)
|
|
{
|
|
toolStripStatusConnected.ForeColor = Color.Crimson;
|
|
toolStripStatusConnected.Text = "Not connected";
|
|
}
|
|
else
|
|
{
|
|
if (mRunning)
|
|
{
|
|
toolStripStatusConnected.ForeColor = Color.Green;
|
|
toolStripStatusConnected.Text = "Debug";
|
|
}
|
|
else
|
|
{
|
|
toolStripStatusConnected.ForeColor = Color.Yellow;
|
|
toolStripStatusConnected.Text = "Waiting";
|
|
}
|
|
}
|
|
|
|
if (mCurrentFile.CompareTo("unknown") != 0)
|
|
{
|
|
toolStripStatusSourceLocation.Visible = true;
|
|
toolStripStatusSourceLocationFile.Text = mCurrentFile;
|
|
toolStripStatusSourceLocationLine.Text = mCurrentLine.ToString();
|
|
toolStripStatusSourceLocationColon.Visible = true;
|
|
}
|
|
else
|
|
{
|
|
toolStripStatusSourceLocation.Visible = false;
|
|
toolStripStatusSourceLocationFile.Text = string.Empty;
|
|
toolStripStatusSourceLocationLine.Text = string.Empty;
|
|
toolStripStatusSourceLocationColon.Visible = false;
|
|
}
|
|
}
|
|
|
|
void DebugModuleChangedEvent(object sender, DebugModuleChangedEventArgs args)
|
|
{
|
|
Module themod;
|
|
if (!mModules.TryGetValue(args.ModuleAddr, out themod) ||
|
|
themod.ShortName != args.ModuleName.ToLower())
|
|
{
|
|
mModules[args.ModuleAddr] = new Module(args.ModuleAddr, args.ModuleName);
|
|
mSymbolContext.LoadModule(args.ModuleName, args.ModuleAddr);
|
|
}
|
|
Invoke(Delegate.CreateDelegate(typeof(NoParamsDelegate), this, "ComposeTitleString"));
|
|
}
|
|
|
|
void DebugRunningChangeEvent(object sender, DebugRunningChangeEventArgs args)
|
|
{
|
|
mRunning = args.Running;
|
|
Invoke(Delegate.CreateDelegate(typeof(NoParamsDelegate), this, "ComposeTitleString"));
|
|
Invoke(Delegate.CreateDelegate(typeof(NoParamsDelegate), this, "UpdateDebuggerMenu"));
|
|
}
|
|
|
|
void DebugConnectionModeChangedEvent(object sender, DebugConnectionModeChangedEventArgs args)
|
|
{
|
|
mConnectionMode = args.Mode;
|
|
Invoke(Delegate.CreateDelegate(typeof(NoParamsDelegate), this, "ComposeTitleString"));
|
|
}
|
|
|
|
void DebugRegisterChangeEvent(object sender, DebugRegisterChangeEventArgs args)
|
|
{
|
|
mCurrentEip = args.Registers.Eip;
|
|
Invoke(Delegate.CreateDelegate(typeof(NoParamsDelegate), this, "ComposeTitleString"));
|
|
}
|
|
|
|
protected override void OnLoad(EventArgs e)
|
|
{
|
|
base.OnLoad(e);
|
|
mSymbolContext.Initialize();
|
|
mConnection.DebugConnectionModeChangedEvent += DebugConnectionModeChangedEvent;
|
|
mConnection.DebugRunningChangeEvent += DebugRunningChangeEvent;
|
|
mConnection.DebugRegisterChangeEvent += DebugRegisterChangeEvent;
|
|
mConnection.DebugModuleChangedEvent += DebugModuleChangedEvent;
|
|
ComposeTitleString();
|
|
mSymbolContext.ReactosOutputPath = Settings.OutputDirectory;
|
|
}
|
|
|
|
public void RegisterControl(Control ctrl)
|
|
{
|
|
IUseDebugConnection usedbg = ctrl as IUseDebugConnection;
|
|
if (usedbg != null)
|
|
usedbg.SetDebugConnection(mConnection);
|
|
IUseSymbols usesym = ctrl as IUseSymbols;
|
|
if (usesym != null)
|
|
usesym.SetSymbolProvider(mSymbolContext);
|
|
IUseShell useshell = ctrl as IUseShell;
|
|
if (useshell != null)
|
|
useshell.SetShell(this);
|
|
}
|
|
|
|
private void OpenFile(object sender, EventArgs e)
|
|
{
|
|
OpenFileDialog fileDialog = new OpenFileDialog();
|
|
fileDialog.Filter = "Sourcefiles (*.c;*.cpp)|*.c;*.cpp";
|
|
if (fileDialog.ShowDialog() == DialogResult.OK)
|
|
{
|
|
OpenSourceFile(fileDialog.FileName);
|
|
}
|
|
}
|
|
|
|
private void ExitToolsStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
this.Close();
|
|
}
|
|
|
|
private void ToolBarToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
toolStrip.Visible = toolBarToolStripMenuItem.Checked;
|
|
}
|
|
|
|
private void StatusBarToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
statusStrip.Visible = statusBarToolStripMenuItem.Checked;
|
|
}
|
|
|
|
private void MainWindowMDI_FormClosing(object sender, FormClosingEventArgs e)
|
|
{
|
|
RosDiagnostics.DebugTrace(RosDiagnostics.TraceType.Info, "Closing application");
|
|
mConnection.Close(true);
|
|
SaveWindowSettings();
|
|
}
|
|
|
|
void UpdateDebuggerMenu()
|
|
{
|
|
if (mConnection.ConnectionMode == DebugConnection.Mode.ClosedMode)
|
|
{
|
|
continueToolStripButton.Enabled = continueToolStripMenuItem.Enabled = false;
|
|
breakToolStripButton.Enabled = breakToolStripMenuItem.Enabled = false;
|
|
nextToolStripButton.Enabled = nextToolStripMenuItem.Enabled = false;
|
|
stepToolStripButton.Enabled = stepToolStripMenuItem.Enabled = false;
|
|
}
|
|
else
|
|
{
|
|
continueToolStripButton.Enabled = continueToolStripMenuItem.Enabled = !mRunning;
|
|
breakToolStripButton.Enabled = breakToolStripMenuItem.Enabled = mRunning;
|
|
nextToolStripButton.Enabled = nextToolStripMenuItem.Enabled = !mRunning;
|
|
stepToolStripButton.Enabled = stepToolStripMenuItem.Enabled = !mRunning;
|
|
}
|
|
}
|
|
|
|
public void FocusAddress(ulong eipToFocus)
|
|
{
|
|
KeyValuePair<string, int> fileline = mSymbolContext.GetFileAndLine(eipToFocus);
|
|
mCurrentFile = fileline.Key;
|
|
mCurrentLine = fileline.Value;
|
|
TryToDisplaySource();
|
|
}
|
|
|
|
void Rehighlight(SourceView vw)
|
|
{
|
|
vw.ClearHighlight();
|
|
vw.AddHighlight(mCurrentLine, Color.SteelBlue, Color.White);
|
|
vw.ScrollTo(mCurrentLine);
|
|
}
|
|
|
|
void TryToDisplaySource()
|
|
{
|
|
if (mCurrentFile == null || mCurrentFile == "unknown") return;
|
|
OpenSourceFile(Path.Combine(mSourceRoot, mCurrentFile));
|
|
}
|
|
|
|
private void OpenSourceFile(string FileName)
|
|
{
|
|
SourceView theSourceView;
|
|
if (File.Exists(FileName))
|
|
{
|
|
if (mSourceFiles.TryGetValue(FileName, out theSourceView))
|
|
Rehighlight(theSourceView);
|
|
else
|
|
{
|
|
theSourceView = new SourceView(Path.GetFileName(FileName));
|
|
mSourceFiles[FileName] = theSourceView;
|
|
theSourceView.SourceFile = FileName;
|
|
Rehighlight(theSourceView);
|
|
theSourceView.Show(dockPanel);
|
|
}
|
|
}
|
|
}
|
|
|
|
public DebugConnection DebugConnection
|
|
{
|
|
get { return mConnection; }
|
|
}
|
|
|
|
private void breakToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
mConnection.Break();
|
|
}
|
|
|
|
private void continueToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
mConnection.Go();
|
|
}
|
|
|
|
private void stepToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
mConnection.Step();
|
|
}
|
|
|
|
private void nextToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
mConnection.Next();
|
|
}
|
|
|
|
private void contentsToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
ReactOSWeb Help = new ReactOSWeb("Help", "http://www.reactos.org/wiki/index.php/ReactOS_Remote_Debugger");
|
|
Help.Show(dockPanel);
|
|
}
|
|
|
|
private void optionsToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
Settings.ShowSettings();
|
|
mSourceRoot = Settings.SourceDirectory;
|
|
mSymbolContext.ReactosOutputPath = Settings.OutputDirectory;
|
|
}
|
|
|
|
private void consoleToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
m_RawTraffic.Show(dockPanel);
|
|
}
|
|
|
|
private void connectToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
if (mConnection.ConnectionMode == DebugConnection.Mode.ClosedMode)
|
|
{
|
|
Connect newConnection = new Connect();
|
|
if (newConnection.ShowDialog() == DialogResult.OK)
|
|
{
|
|
mConnection.Close();
|
|
switch (newConnection.Type)
|
|
{
|
|
case Connect.ConnectionType.Serial:
|
|
mConnection.StartSerial(newConnection.ComPort, newConnection.Baudrate);
|
|
break;
|
|
case Connect.ConnectionType.Pipe:
|
|
mConnection.StartPipe(newConnection.PipeName, newConnection.PipeMode);
|
|
break;
|
|
case Connect.ConnectionType.Socket:
|
|
mConnection.StartTCP(newConnection.Host, newConnection.Port);
|
|
break;
|
|
}
|
|
if (mConnection.ConnectionMode != DebugConnection.Mode.ClosedMode)
|
|
{
|
|
connectToolStripMenuItem.Text = "&Disconnect";
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
mConnection.Close();
|
|
UpdateDebuggerMenu();
|
|
connectToolStripMenuItem.Text = "&Connect";
|
|
}
|
|
}
|
|
|
|
private void memoryToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
m_MemoryWindow.Show(dockPanel);
|
|
}
|
|
|
|
private void webbrowserToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
ReactOSWeb web = new ReactOSWeb();
|
|
web.Show(dockPanel);
|
|
}
|
|
|
|
private void registerToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
m_RegView.Show(dockPanel, DockState.DockRight);
|
|
}
|
|
|
|
private void localsToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
m_Locals.Show(dockPanel, DockState.DockRight);
|
|
}
|
|
|
|
private void procThreadToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
m_ProcThread.Show(dockPanel);
|
|
}
|
|
|
|
private void modulesToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
m_Modules.Show(dockPanel);
|
|
}
|
|
|
|
private void backtraceToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
m_BackTrace.Show(dockPanel, DockState.DockBottom);
|
|
}
|
|
|
|
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
((ToolWindow)dockPanel.ActiveDocument.DockHandler.Form).Save(
|
|
((ToolWindow)dockPanel.ActiveDocument.DockHandler.Form).GetDocumentName());
|
|
}
|
|
|
|
private void SaveAsToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
((ToolWindow)dockPanel.ActiveDocument.DockHandler.Form).SaveAs(
|
|
((ToolWindow)dockPanel.ActiveDocument.DockHandler.Form).GetDocumentName());
|
|
}
|
|
|
|
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
AboutDlg about = new AboutDlg();
|
|
about.ShowDialog(this);
|
|
}
|
|
|
|
protected override void OnFormClosing(FormClosingEventArgs e)
|
|
{
|
|
base.OnFormClosing(e);
|
|
dockPanel.ActiveDocumentChanged -= dockPanel_ActiveDocumentChanged;
|
|
}
|
|
|
|
private void dockPanel_ActiveDocumentChanged(object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
ToolWindow Wnd = (ToolWindow)dockPanel.ActiveDocument.DockHandler.Form;
|
|
|
|
saveToolStripButton.Enabled = Wnd.IsCmdEnabled(ToolWindow.Commands.Save);
|
|
saveToolStripMenuItem.Enabled = Wnd.IsCmdEnabled(ToolWindow.Commands.Save);
|
|
saveAsToolStripMenuItem.Enabled = Wnd.IsCmdEnabled(ToolWindow.Commands.SaveAs);
|
|
printToolStripButton.Enabled = Wnd.IsCmdEnabled(ToolWindow.Commands.Print);
|
|
printToolStripMenuItem.Enabled = Wnd.IsCmdEnabled(ToolWindow.Commands.Print);
|
|
}
|
|
catch (NullReferenceException ex)
|
|
{
|
|
RosDiagnostics.DebugTrace(RosDiagnostics.TraceType.Exception, "Null reference : " + ex.Message);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
RosDiagnostics.DebugTrace(RosDiagnostics.TraceType.Exception, "Unexpected error");
|
|
}
|
|
}
|
|
|
|
private void printToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
((ToolWindow)dockPanel.ActiveDocument.DockHandler.Form).Print(true);
|
|
}
|
|
|
|
private void printToolStripButton_Click(object sender, EventArgs e)
|
|
{
|
|
((ToolWindow)dockPanel.ActiveDocument.DockHandler.Form).Print(false);
|
|
}
|
|
|
|
private void stepToolStripButton_Click(object sender, EventArgs e)
|
|
{
|
|
stepToolStripMenuItem_Click(sender, e);
|
|
}
|
|
|
|
private void nextToolStripButton_Click(object sender, EventArgs e)
|
|
{
|
|
nextToolStripMenuItem_Click(sender, e);
|
|
}
|
|
|
|
private void externalToolsToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
ExtTools exTools = new ExtTools();
|
|
if (exTools.ShowDialog(this) == DialogResult.OK)
|
|
{
|
|
Settings.Save();
|
|
UpdateExternalToolsMenu();
|
|
}
|
|
}
|
|
|
|
private void UpdateExternalToolsMenu()
|
|
{
|
|
int i = 0;
|
|
bool bFirst = true;
|
|
while (true)
|
|
{
|
|
if ((toolsMenu.DropDownItems[i].Tag != null) &&
|
|
(toolsMenu.DropDownItems[i].Tag.ToString() == "tool"))
|
|
toolsMenu.DropDownItems.Remove(toolsMenu.DropDownItems[i]);
|
|
else
|
|
i++;
|
|
if (i >= toolsMenu.DropDownItems.Count - 1)
|
|
break;
|
|
}
|
|
if (Settings.ExternalTools != null)
|
|
{
|
|
foreach (object o in Settings.ExternalTools)
|
|
{
|
|
ToolStripMenuItem item = new ToolStripMenuItem(o.ToString(), null,
|
|
new System.EventHandler(this.LaunchExternalToolToolStripMenuItem_Click),
|
|
((ExternalTool)o).Path);
|
|
item.Tag = "tool";
|
|
toolsMenu.DropDownItems.Insert(bFirst ? 0 : 1, item);
|
|
bFirst = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void MainWindow_Load(object sender, EventArgs e)
|
|
{
|
|
UpdateExternalToolsMenu();
|
|
}
|
|
|
|
private void LaunchExternalToolToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
Process.Start(((ToolStripMenuItem)sender).Name);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
|
|
}
|
|
}
|
|
private void SaveWindowSettings()
|
|
{
|
|
RosDBG.Properties.Settings.Default.Size = this.Size;
|
|
RosDBG.Properties.Settings.Default.Location = this.Location;
|
|
RosDBG.Properties.Settings.Default.WindowState = this.WindowState;
|
|
RosDBG.Properties.Settings.Default.Save();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|