Отладчик под Linux, что-то работающее (пока только в DEBUG-версии)

This commit is contained in:
Ivan Bondarev 2023-05-28 14:20:57 +02:00
parent 41d9e2ab1b
commit 1c0ba55bad
14 changed files with 524 additions and 227 deletions

View file

@ -378,6 +378,7 @@ namespace VisualPascalABC
RemoveFromTables(fileName);
if (Exited != null)
Exited(fileName);
}
void RemoveFromTables(string FileName)
@ -407,6 +408,7 @@ namespace VisualPascalABC
(StartedProcesses[fileName] as Utils.ProcessRunner).Kill();
if (!WorkbenchServiceFactory.Workbench.UserOptions.AlwaysAttachDebuggerAtStart)
WorkbenchServiceFactory.Workbench.DebuggerManager.NullProcessHandleIfNeed(fileName);
WorkbenchServiceFactory.DebuggerManager.EndDebuggerSession();
RemoveFromTables(fileName);
if (Exited != null)
Exited(fileName);

View file

@ -216,7 +216,10 @@ namespace VisualPascalABC.Utils
RedirectIO=redirectIO;
process = new Process();
string BatFile = null;
process.StartInfo.ErrorDialog = false;
#if (!DEBUG)
attachDebugger = false;
#endif
process.StartInfo.ErrorDialog = false;
if (RunWithPause && (BatFile = Path.Combine(Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath),"ProgrammRunner.exe")/*GenerateBatFileForRunWithPause(command, arguments)*/) != null)
{
TempBatFile = BatFile;
@ -260,21 +263,33 @@ namespace VisualPascalABC.Utils
process.StartInfo.RedirectStandardError = true;
process.StartInfo.StandardErrorEncoding = System.Text.Encoding.UTF8;
}
if (ProcessExited != null)
bool dbgFailed = false;
if (attachDebugger && !fictive_attach)
{
var dbgProcess = WorkbenchServiceFactory.DebuggerManager.RunWithMonoDebugger(process.StartInfo, command, arguments);
if (dbgProcess != null)
{
process = dbgProcess;
process.PriorityClass = ProcessPriorityClass.BelowNormal;
}
else
dbgFailed = true;
}
if (ProcessExited != null)
{
process.EnableRaisingEvents = true;
process.Exited += new EventHandler(OnProcessExited);
}
process.Start();
//ssyy
process.PriorityClass = ProcessPriorityClass.BelowNormal;
//\ssyy
if (attachDebugger)
if (!attachDebugger || dbgFailed || fictive_attach)
{
WorkbenchServiceFactory.DebuggerManager.Attach((uint)process.Id,command,!fictive_attach,false);
}
if (redirectIO)
process.StandardInput.WriteLine("GO");
process.Start();
//ssyy
process.PriorityClass = ProcessPriorityClass.BelowNormal;
//\ssyy
}
if (redirectIO)
process.StandardInput.WriteLine("GO");
}

View file

@ -510,8 +510,8 @@ namespace VisualPascalABC
public class BreakPointFactory
{
public static Dictionary<CurrentBreakpointBookmark, Breakpoint> breakpoints = new Dictionary<CurrentBreakpointBookmark, Breakpoint>();
public static Dictionary<Breakpoint,BreakpointInfo> breakpoints_conditions = new Dictionary<Breakpoint,BreakpointInfo>();
public static Dictionary<CurrentBreakpointBookmark, Mono.Debugging.Client.Breakpoint> breakpoints = new Dictionary<CurrentBreakpointBookmark, Mono.Debugging.Client.Breakpoint>();
public static Dictionary<Mono.Debugging.Client.Breakpoint, BreakpointInfo> breakpoints_conditions = new Dictionary<Mono.Debugging.Client.Breakpoint, BreakpointInfo>();
static BreakPointFactory()
{
@ -519,7 +519,7 @@ namespace VisualPascalABC
private static BreakpointConditionForm bcf;
public static bool MustHit(Breakpoint br)
public static bool MustHit(Mono.Debugging.Client.Breakpoint br)
{
BreakpointInfo bi = null;
if (breakpoints_conditions.TryGetValue(br,out bi))
@ -584,7 +584,7 @@ namespace VisualPascalABC
Form1StringResources.SetTextForAllControls(bcf);
}
BreakpointInfo bi = null;
Breakpoint br = breakpoints[cur_bookmark];
Mono.Debugging.Client.Breakpoint br = breakpoints[cur_bookmark];
if (breakpoints_conditions.TryGetValue(br,out bi))
{
bcf.IsConditionEnabled = bi.enabled;
@ -620,14 +620,14 @@ namespace VisualPascalABC
public static void AddBreakpoints(string FileName, TextArea text_area)
{
List<Breakpoint> br_list = WorkbenchServiceFactory.DebuggerManager.GetBreakpointsInFile(FileName);
foreach (Breakpoint br in br_list)
List<Mono.Debugging.Client.Breakpoint> br_list = WorkbenchServiceFactory.DebuggerManager.GetBreakpointsInFile(FileName);
foreach (Mono.Debugging.Client.Breakpoint br in br_list)
{
ToggleBreakpointAtByOpen(text_area.Document, br.SourcecodeSegment.SourceFullFilename, br.SourcecodeSegment.StartLine-1, br);
ToggleBreakpointAtByOpen(text_area.Document, br.FileName, br.Line-1, br);
}
}
public static void ToggleBreakpointAtByOpen(IDocument document, string fileName, int lineNumber, Breakpoint br)
public static void ToggleBreakpointAtByOpen(IDocument document, string fileName, int lineNumber, Mono.Debugging.Client.Breakpoint br)
{
foreach (char ch in document.GetText(document.GetLineSegment(lineNumber)))
{

View file

@ -295,7 +295,7 @@ namespace VisualPascalABC
private string FileName;
private string FullFileName;
private string PrevFullFileName;
private Breakpoint brPoint;
private Mono.Debugging.Client.Breakpoint brPoint;
private Breakpoint currentBreakpoint;
private int CurrentLine;
public DebugStatus Status;
@ -305,13 +305,18 @@ namespace VisualPascalABC
public bool ShowDebugTabs=true;
public PascalABCCompiler.Parsers.IParser parser = null;
EventHandler<EventArgs> debuggerStateEvent;
private Mono.Debugging.Soft.SoftDebuggerSession monoDebuggerSession;
private Mono.Debugging.Client.StackFrame stackFrame;
public DebugHelper()
{
//System.Threading.Thread.CurrentThread.SetApartmentState(System.Threading.ApartmentState.MTA);
dbg = new NDebugger();
monoDebuggerSession = new Mono.Debugging.Soft.SoftDebuggerSession();
//th = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(frm.RefreshPad));
this.workbench = WorkbenchServiceFactory.Workbench;
}
public Process DebuggedProcess
@ -344,24 +349,24 @@ namespace VisualPascalABC
/// <summary>
/// Добавить Breakpoint в файл fileName строку line
/// </summary>
public Breakpoint AddBreakPoint(string fileName, int line, bool commonBreakpoint)
public Mono.Debugging.Client.Breakpoint AddBreakPoint(string fileName, int line, bool commonBreakpoint)
{
Breakpoint br = null;
Mono.Debugging.Client.Breakpoint br = null;
bool added = false;
if (!workbench.UserOptions.AlwaysAttachDebuggerAtStart && handle != 0 && commonBreakpoint && this.debuggedProcess == null)
{
Attach(handle, ExeFileName, true,true);
}
foreach (Breakpoint bp in dbg.Breakpoints)
foreach (Mono.Debugging.Client.Breakpoint bp in monoDebuggerSession.Breakpoints.GetBreakpoints())
{
if (bp.SourcecodeSegment.SourceFullFilename == fileName && bp.SourcecodeSegment.StartLine == line)
if (bp.FileName == fileName && bp.Line == line)
{
added = true;
br = bp;
}
}
if (!added)
br = dbg.AddBreakpoint(fileName, line);
br = monoDebuggerSession.Breakpoints.Add(fileName, line);
return br;
}
@ -369,12 +374,12 @@ namespace VisualPascalABC
/// <summary>
/// Получить список Breakpointov в файле fileName
/// </summary>
public List<Breakpoint> GetBreakpointsInFile(string fileName)
public List<Mono.Debugging.Client.Breakpoint> GetBreakpointsInFile(string fileName)
{
List<Breakpoint> lst = new List<Breakpoint>();
foreach (Breakpoint bp in dbg.Breakpoints)
List<Mono.Debugging.Client.Breakpoint> lst = new List<Mono.Debugging.Client.Breakpoint>();
foreach (Mono.Debugging.Client.Breakpoint bp in monoDebuggerSession.Breakpoints.GetBreakpoints())
{
if (bp.SourcecodeSegment.SourceFullFilename == fileName)
if (bp.FileName == fileName)
{
lst.Add(bp);
}
@ -385,9 +390,9 @@ namespace VisualPascalABC
/// <summary>
/// Удалить Breakpoint
/// </summary>
public void RemoveBreakpoint(Breakpoint br)
public void RemoveBreakpoint(Mono.Debugging.Client.Breakpoint br)
{
dbg.RemoveBreakpoint(br);
monoDebuggerSession.Breakpoints.Remove(br);
}
public delegate void DebugHelperActionDelegate(string FileName);
@ -416,7 +421,7 @@ namespace VisualPascalABC
this.FullFileName = Path.Combine(Path.GetDirectoryName(fileName), this.FileName);
this.ExeFileName = fileName;
this.PrevFullFileName = FullFileName;
if (need_first_brpt) brPoint = dbg.AddBreakpoint(FileName, workbench.VisualEnvironmentCompiler.Compiler.BeginOffset);
//if (need_first_brpt) brPoint = dbg.AddBreakpoint(FileName, workbench.VisualEnvironmentCompiler.Compiler.BeginOffset);
AssemblyHelper.LoadAssembly(fileName);
debuggedProcess = dbg.Start(fileName, workingDirectory, arguments);
SelectProcess(debuggedProcess);
@ -426,6 +431,7 @@ namespace VisualPascalABC
public void NullProcessHandleIfNeed(string fileName)
{
Console.WriteLine("null process handle");
if (string.Compare(fileName,this.ExeFileName,true)==0)
{
FileName = null;
@ -436,7 +442,8 @@ namespace VisualPascalABC
ExeFileName = null;
WorkbenchServiceFactory.OperationsService.ClearTabStack();
WorkbenchServiceFactory.DebuggerOperationsService.ClearDebugTabs();
WorkbenchServiceFactory.Workbench.DisassemblyWindow.ClearWindow();
if (WorkbenchServiceFactory.Workbench.DisassemblyWindow != null)
WorkbenchServiceFactory.Workbench.DisassemblyWindow.ClearWindow();
}
}
}
@ -454,8 +461,8 @@ namespace VisualPascalABC
return;
if (Starting != null)
Starting(fileName);
string sourceFileName = null;
string sourceFileName = null;
if (!ProjectFactory.Instance.ProjectLoaded)
sourceFileName = workbench.VisualEnvironmentCompiler.Compiler.CompilerOptions.SourceFileName;
else
@ -467,19 +474,157 @@ namespace VisualPascalABC
this.parser = CodeCompletion.CodeCompletionController.ParsersController.selectParser(Path.GetExtension(FullFileName).ToLower());
this.PrevFullFileName = FullFileName;
AssemblyHelper.LoadAssembly(fileName);
dbg.ProcessStarted += debugProcessStarted;
dbg.ProcessExited += debugProcessExit;
//brPoint = dbg.AddBreakpoint(FileName, frm.VisualEnvironmentCompiler.Compiler.BeginOffset);
//dbg.ProcessStarted += debugProcessStarted;
//dbg.ProcessExited += debugProcessExit;
monoDebuggerSession.TargetHitBreakpoint += MonoDebuggerSession_TargetHitBreakpoint;
monoDebuggerSession.AttachToProcess(new Mono.Debugging.Client.ProcessInfo(handle, fileName), new Mono.Debugging.Client.DebuggerSessionOptions());
}
public System.Diagnostics.Process RunWithMonoDebugger(System.Diagnostics.ProcessStartInfo psi, string fileName, string args)
{
if (Starting != null)
Starting(fileName);
string sourceFileName = null;
if (!ProjectFactory.Instance.ProjectLoaded)
sourceFileName = workbench.VisualEnvironmentCompiler.Compiler.CompilerOptions.SourceFileName;
else
sourceFileName = ProjectFactory.Instance.CurrentProject.MainFile;
this.FileName = sourceFileName;//Path.GetFileNameWithoutExtension(fileName) + ".pas";
this.FullFileName = Path.Combine(Path.GetDirectoryName(fileName), this.FileName);
this.ExeFileName = fileName;
CurrentLine = 0;
this.parser = CodeCompletion.CodeCompletionController.ParsersController.selectParser(Path.GetExtension(FullFileName).ToLower());
this.PrevFullFileName = FullFileName;
AssemblyHelper.LoadAssembly(fileName);
Mono.Debugging.Client.DebuggerSessionOptions dso = new Mono.Debugging.Client.DebuggerSessionOptions();
dso.EvaluationOptions = Mono.Debugging.Client.EvaluationOptions.DefaultOptions.Clone();
//monoDebuggerSession.AttachToProcess(new Mono.Debugging.Client.ProcessInfo(handle, fileName), dso);
Mono.Debugging.Soft.SoftDebuggerStartInfo dsi = new Mono.Debugging.Soft.SoftDebuggerStartInfo("", new Dictionary<string, string>());
dsi.Command = fileName;
dsi.Arguments = args;
dsi.StartArgs = new Mono.Debugging.Soft.SoftDebuggerLaunchArgs("", new Dictionary<string, string>());
dsi.WorkingDirectory = psi.WorkingDirectory;
try
{
debuggedProcess = dbg.DebugActiveProcess(handle, fileName);
monoDebuggerSession.TargetHitBreakpoint += MonoDebuggerSession_TargetHitBreakpoint;
monoDebuggerSession.TargetStopped += MonoDebuggerSession_TargetStopped;
monoDebuggerSession.TargetStarted += MonoDebuggerSession_TargetStarted;
//monoDebuggerSession.TargetThreadStopped += MonoDebuggerSession_TargetThreadStopped;
monoDebuggerSession.Run(dsi, dso);
int i = 0;
while (Mono.Debugger.Soft.VirtualMachineManager.currentProcess == null && i < 5)
{
System.Threading.Thread.Sleep(100);
i++;
}
workbench.WidgetController.SetDebugTabsVisible(true);
workbench.WidgetController.SetPlayButtonsVisible(true);
workbench.WidgetController.SetDebugStopEnabled();//e.Process.LogMessage += messageEventProc;
workbench.WidgetController.SetStartDebugDisabled();
workbench.WidgetController.ChangeStartDebugNameOnContinue();
workbench.WidgetController.EnableCodeCompletionToolTips(false);
workbench.WidgetController.SetAddExprMenuVisible(true);
workbench.WidgetController.SetDisassemblyMenuVisible(true);
workbench.ServiceContainer.EditorService.SetEditorDisabled(true);
TooltipServiceManager.hideToolTip();
IsRunning = true;
//evaluator = new ExpressionEvaluator(e.Process, workbench.VisualEnvironmentCompiler, FileName);
var process = (Mono.Debugger.Soft.VirtualMachineManager.currentProcess as Mono.Debugger.Soft.ProcessWrapper).Process;
process.Exited += Process_Exited;
return (Mono.Debugger.Soft.VirtualMachineManager.currentProcess as Mono.Debugger.Soft.ProcessWrapper).Process;
}
catch (System.Exception ex)
{
return;
Console.WriteLine(ex.Message);
}
SelectProcess(debuggedProcess);
//debuggedProcess.Break();
return null;
}
public void EndDebuggerSession()
{
if (Mono.Debugger.Soft.VirtualMachineManager.currentProcess == null)
return;
if (Exited != null && ExeFileName != null)
Exited(ExeFileName);
curPage = null;
ShowDebugTabs = true;
workbench.WidgetController.SetPlayButtonsVisible(false);
workbench.WidgetController.SetAddExprMenuVisible(false);
workbench.WidgetController.SetDisassemblyMenuVisible(false);
if (DebugWatchListWindowForm.WatchWindow != null)
DebugWatchListWindowForm.WatchWindow.ClearAllSubTrees();
IsRunning = false;
workbench.WidgetController.SetDebugStopDisabled();
workbench.WidgetController.ChangeContinueDebugNameOnStart();
CurrentLineBookmark.Remove();
WorkbenchServiceFactory.DebuggerOperationsService.ClearLocalVarTree();
WorkbenchServiceFactory.DebuggerOperationsService.ClearDebugTabs();
WorkbenchServiceFactory.DebuggerOperationsService.ClearWatch();
if (WorkbenchServiceFactory.Workbench.DisassemblyWindow != null)
WorkbenchServiceFactory.Workbench.DisassemblyWindow.ClearWindow();
workbench.WidgetController.SetDebugTabsVisible(false);
WorkbenchServiceFactory.OperationsService.ClearTabStack();
workbench.WidgetController.EnableCodeCompletionToolTips(true);
RemoveGotoBreakpoints();
AssemblyHelper.Unload();
CloseOldToolTip();
workbench.ServiceContainer.EditorService.SetEditorDisabled(false);
//RemoveMarker(frm.CurrentCodeFileDocument.TextEditor.ActiveTextAreaControl.Document);
evaluator = null;
parser = null;
FileName = null;
handle = 0;
ExeFileName = null;
FullFileName = null;
PrevFullFileName = null;
stackFrame = null;
monoDebuggerSession.TargetHitBreakpoint -= MonoDebuggerSession_TargetHitBreakpoint;
monoDebuggerSession.TargetStopped -= MonoDebuggerSession_TargetStopped;
monoDebuggerSession.TargetStarted -= MonoDebuggerSession_TargetStarted;
//monoDebuggerSession.TargetThreadStopped -= MonoDebuggerSession_TargetThreadStopped;
Status = DebugStatus.None;
Mono.Debugger.Soft.VirtualMachineManager.currentProcess = null;
monoDebuggerSession = new Mono.Debugging.Soft.SoftDebuggerSession();
}
private void Process_Exited(object sender, EventArgs e)
{
EndDebuggerSession();
}
private void MonoDebuggerSession_TargetThreadStopped(object sender, Mono.Debugging.Client.TargetEventArgs e)
{
stackFrame = e.Thread.Backtrace.GetFrame(0);
JumpToCurrentLine();
}
private void MonoDebuggerSession_TargetStopped(object sender, Mono.Debugging.Client.TargetEventArgs e)
{
stackFrame = e.Thread.Backtrace.GetFrame(0);
JumpToCurrentLine();
workbench.WidgetController.SetStartDebugEnabled();
}
private void MonoDebuggerSession_TargetStarted(object sender, EventArgs e)
{
stackFrame = null;
}
private void MonoDebuggerSession_TargetHitBreakpoint(object sender, Mono.Debugging.Client.TargetEventArgs e)
{
stackFrame = e.Thread.Backtrace.GetFrame(0);
JumpToCurrentLine();
workbench.WidgetController.SetStartDebugEnabled();
}
Function currentFunction;
@ -555,7 +700,9 @@ namespace VisualPascalABC
public void SetFirstBreakpoint(string fileName, int line)
{
brPoint = dbg.AddBreakpoint(fileName, line);
//brPoint = dbg.AddBreakpoint(fileName, line);
brPoint = new Mono.Debugging.Client.Breakpoint(fileName, line, 1);
monoDebuggerSession.Breakpoints.Add(brPoint);
}
private void SelectProcess(Debugger.Process process)
@ -633,7 +780,7 @@ namespace VisualPascalABC
{
if (brPoint != null)
{
dbg.RemoveBreakpoint(brPoint);
monoDebuggerSession.Breakpoints.Remove(brPoint);
brPoint = null;
}
}
@ -828,185 +975,178 @@ namespace VisualPascalABC
private ICodeFileDocument curPage;
private bool is_out = false;
private SourcecodeSegment stepin_stmt = null;
private Mono.Debugging.Client.SourceLocation stepin_stmt = null;
private bool tab_changed=false;
/// <summary>
/// Перейти к следующей строке при отладке
/// </summary>
private void JumpToCurrentLine()
private void JumpToCurrentLine(bool fromBreakpoint = false)
{
workbench.MainForm.Activate();
CurrentLineBookmark.Remove();//udalajem zheltyj kursor otladki
//System.Threading.Thread.Sleep(70);
if (debuggedProcess != null)
if (stackFrame != null)
{
SourcecodeSegment nextStatement = debuggedProcess.NextStatement;
//debuggedProcess.Modules[0].SymReader.GetMethod(debuggedProcess.SelectedFunction.Token);
if (nextStatement != null)
string save_PrevFullFileName = PrevFullFileName;
Console.WriteLine(stackFrame.SourceLocation.FileName + ":" + stackFrame.SourceLocation.Line);
//CodeFileDocumentControl page = null;
//DebuggerService.JumpToCurrentLine(nextStatement.SourceFullFilename, nextStatement.StartLine, nextStatement.StartColumn, nextStatement.EndLine, nextStatement.EndColumn);
if (!ShowDebugTabs)//esli eshe ne pokazany watch i lokal, pokazyvaem
{
string save_PrevFullFileName = PrevFullFileName;
//CodeFileDocumentControl page = null;
//DebuggerService.JumpToCurrentLine(nextStatement.SourceFullFilename, nextStatement.StartLine, nextStatement.StartColumn, nextStatement.EndLine, nextStatement.EndColumn);
if (!ShowDebugTabs)//esli eshe ne pokazany watch i lokal, pokazyvaem
ShowDebugTabs = true;
workbench.WidgetController.SetDebugTabsVisible(true);
workbench.WidgetController.SetAddExprMenuVisible(true);
}
if (stackFrame.SourceLocation.Line == 0xFFFFFF)
{
//sjuda popadem, esli vyzyvaem Test(arr), gde arr - massiv peredavaemyj po znacheniju
//metod $Copy ne imeet sequence pointov, poetomu chtoby vojti v proceduru vyzovy $Copy my pomechaem 0xFFFFFFF
//dolgo s etoj badjagoj muchalsja
is_out = true;
monoDebuggerSession.StepLine();//vhodim neposredstvenno v proceduru
return;
}
/*else if (AssemblyHelper.IsDebuggerStepThrough(stackFrame))
{
MustDebug = true;
monoDebuggerSession.StepLine();
return;
}*/
else if (is_out)
{
is_out = false;
if (stepin_stmt.FileName == stackFrame.SourceLocation.FileName && stepin_stmt.Line != stackFrame.SourceLocation.Line)
stepin_stmt = stackFrame.SourceLocation;
else
{
ShowDebugTabs = true;
workbench.WidgetController.SetDebugTabsVisible(true);
workbench.WidgetController.SetAddExprMenuVisible(true);
}
if (debuggedProcess.NextStatement.StartLine == 0xFFFFFF)
{
//sjuda popadem, esli vyzyvaem Test(arr), gde arr - massiv peredavaemyj po znacheniju
//metod $Copy ne imeet sequence pointov, poetomu chtoby vojti v proceduru vyzovy $Copy my pomechaem 0xFFFFFFF
//dolgo s etoj badjagoj muchalsja
is_out = true;
debuggedProcess.StepInto();//vhodim neposredstvenno v proceduru
monoDebuggerSession.StepLine();
return;
}
else if (AssemblyHelper.IsDebuggerStepThrough(debuggedProcess.SelectedFunction))
}
if (stackFrame.SourceLocation.FileName != this.PrevFullFileName || !WorkbenchServiceFactory.DocumentService.ContainsTab(stackFrame.SourceLocation.FileName))
{
tab_changed = true;
curPage = WorkbenchServiceFactory.FileService.OpenFileForDebug(stackFrame.SourceLocation.FileName);
if (curPage == null)
{
MustDebug = true;
debuggedProcess.StepOut();
return;
}
else if (is_out)
PrevFullFileName = stackFrame.SourceLocation.FileName;
}
else if (curPage != WorkbenchServiceFactory.DocumentService.CurrentCodeFileDocument)
WorkbenchServiceFactory.DocumentService.CurrentCodeFileDocument = curPage;
bool remove_breakpoints = true;
IDocument doc = curPage.TextEditor.Document;
curTextArea = curPage.TextEditor.ActiveTextAreaControl.TextArea;
LineSegment lseg = curPage.TextEditor.ActiveTextAreaControl.Document.GetLineSegment(stackFrame.SourceLocation.Line - 1);
int len = lseg.Length + 1;
/*if (lseg.Words.Count == 1 && string.Compare(lseg.Words[0].Word,"begin",true)==0)
{
debuggedProcess.StepOver();
return;
}*/
//eto badjaga prepjatstvuet popadaniju na begin
//luchshego sposoba naverno net
bool in_comm = false;
bool beg = false;
bool in_str = false;
for (int i = 0; i < lseg.Words.Count; i++)
{
if (lseg.Words[i].Type == TextWordType.Word)
{
is_out = false;
if (stepin_stmt.SourceFullFilename == debuggedProcess.NextStatement.SourceFullFilename && stepin_stmt.StartLine != debuggedProcess.NextStatement.StartLine)
stepin_stmt = debuggedProcess.NextStatement;
else
string word = lseg.Words[i].Word;
if (string.Compare(word, "begin", true) == 0 && !in_str && !in_comm)
beg = true;
else if (string.Compare(word, "{") == 0)
{
debuggedProcess.StepInto();
return;
if (!in_str) in_comm = true;
}
}
if (debuggedProcess.NextStatement.SourceFullFilename != this.PrevFullFileName || !WorkbenchServiceFactory.DocumentService.ContainsTab(debuggedProcess.NextStatement.SourceFullFilename))
{
tab_changed = true;
curPage = WorkbenchServiceFactory.FileService.OpenFileForDebug(debuggedProcess.NextStatement.SourceFullFilename);
if (curPage == null)
else if (string.Compare(word, "}") == 0)
{
MustDebug = true;
return;
if (!in_str && in_comm) in_comm = false;
}
PrevFullFileName = debuggedProcess.NextStatement.SourceFullFilename;
}
else if (curPage != WorkbenchServiceFactory.DocumentService.CurrentCodeFileDocument)
WorkbenchServiceFactory.DocumentService.CurrentCodeFileDocument = curPage;
bool remove_breakpoints = true;
IDocument doc = curPage.TextEditor.Document;
curTextArea = curPage.TextEditor.ActiveTextAreaControl.TextArea;
LineSegment lseg = curPage.TextEditor.ActiveTextAreaControl.Document.GetLineSegment(debuggedProcess.NextStatement.StartLine - 1);
int len = lseg.Length + 1;
/*if (lseg.Words.Count == 1 && string.Compare(lseg.Words[0].Word,"begin",true)==0)
{
debuggedProcess.StepOver();
return;
}*/
//eto badjaga prepjatstvuet popadaniju na begin
//luchshego sposoba naverno net
bool in_comm = false;
bool beg = false;
bool in_str = false;
for (int i = 0; i < lseg.Words.Count; i++)
{
if (lseg.Words[i].Type == TextWordType.Word)
else if (string.Compare(word, "'") == 0)
in_str = !in_str;
else if (string.Compare(word, "/") == 0)
{
string word = lseg.Words[i].Word;
if (string.Compare(word, "begin", true) == 0 && !in_str && !in_comm)
beg = true;
else if (string.Compare(word, "{") == 0)
{
if (!in_str) in_comm = true;
}
else if (string.Compare(word, "}") == 0)
{
if (!in_str && in_comm) in_comm = false;
}
else if (string.Compare(word, "'") == 0)
in_str = !in_str;
else if (string.Compare(word, "/") == 0)
{
if (i < lseg.Words.Count - 1 && string.Compare(lseg.Words[i + 1].Word, "/") == 0)
break;
}
else if (string.Compare(word, "(") == 0)
{
if (i < lseg.Words.Count - 1 && string.Compare(lseg.Words[i + 1].Word, "*") == 0)
{
beg = false;
break;
}
}
else if (!in_str && !in_comm)
if (i < lseg.Words.Count - 1 && string.Compare(lseg.Words[i + 1].Word, "/") == 0)
break;
}
else if (string.Compare(word, "(") == 0)
{
if (i < lseg.Words.Count - 1 && string.Compare(lseg.Words[i + 1].Word, "*") == 0)
{
beg = false;
break;
}
}
}
if (beg)
{
if (debuggedProcess.PausedReason != PausedReason.Exception)
debuggedProcess.StepOver();
return;
}
if (debuggedProcess.PausedReason == PausedReason.Breakpoint)
{
Breakpoint br = dbg.GetBreakpoint(debuggedProcess.NextStatement.SourceFullFilename, nextStatement.StartLine);
if (br != null && !BreakPointFactory.MustHit(br))
else if (!in_str && !in_comm)
{
if (Status == DebugStatus.StepOver || Status == DebugStatus.StepIn)
{
remove_breakpoints = false;
}
else
{
debuggedProcess.Continue();
return;
}
beg = false;
break;
}
}
//for (int i=0; i<lseg.Words.Count; i++)
CurrentLineBookmark.SetPosition(debuggedProcess.NextStatement.SourceFilename, curPage.TextEditor.Document, nextStatement.StartLine, 1, nextStatement.StartLine,
len);
curPage.TextEditor.ActiveTextAreaControl.JumpTo(nextStatement.StartLine - 1, 0);
}
if (beg)
{
monoDebuggerSession.NextLine();
return;
}
if (fromBreakpoint)
{
var br = monoDebuggerSession.Breakpoints.Add(stackFrame.SourceLocation.FileName, stackFrame.SourceLocation.Line);
if (br != null && !BreakPointFactory.MustHit(br))
{
if (Status == DebugStatus.StepOver || Status == DebugStatus.StepIn)
{
remove_breakpoints = false;
}
else
{
monoDebuggerSession.Continue();
return;
}
}
}
//for (int i=0; i<lseg.Words.Count; i++)
CurrentLineBookmark.SetPosition(stackFrame.SourceLocation.FileName, curPage.TextEditor.Document, stackFrame.SourceLocation.Line, 1, stackFrame.SourceLocation.Line,
len);
curPage.TextEditor.ActiveTextAreaControl.JumpTo(stackFrame.SourceLocation.Line - 1, 0);
if ((Status == DebugStatus.StepOver || Status == DebugStatus.StepIn) && (CurrentLine == nextStatement.StartLine && save_PrevFullFileName == debuggedProcess.NextStatement.SourceFilename))
if ((Status == DebugStatus.StepOver || Status == DebugStatus.StepIn) && (CurrentLine == stackFrame.SourceLocation.Line
&& save_PrevFullFileName == stackFrame.SourceLocation.FileName))
{
if (curILOffset != stackFrame.Address)
{
if (curILOffset != nextStatement.ILOffset)
{
curILOffset = nextStatement.ILOffset;
//debuggedProcess.StepOver();
MustDebug = true;
}
CurrentLine = nextStatement.StartLine;
//return;
}
else
{
curILOffset = nextStatement.ILOffset;
CurrentLine = nextStatement.StartLine;
MustDebug = false;
//MustDebug = ((nextStatement.ILOffset + 1) == nextStatement.ILEnd);
}
//MustDebug = false;
//if (remove_breakpoints)
{
RemoveBreakpoints();
if (currentBreakpoint != null)
{
dbg.RemoveBreakpoint(currentBreakpoint);
currentBreakpoint = null; //RemoveBreakpoints();
}
curILOffset = stackFrame.Address;
//debuggedProcess.StepOver();
MustDebug = true;
}
CurrentLine = stackFrame.SourceLocation.Line;
//return;
}
else
{
curILOffset = stackFrame.Address;
CurrentLine = stackFrame.SourceLocation.Line;
MustDebug = false;
}
RemoveBreakpoints();
if (currentBreakpoint != null)
{
dbg.RemoveBreakpoint(currentBreakpoint);
currentBreakpoint = null; //RemoveBreakpoints();
}
}
}
private int curILOffset = 0;
private long curILOffset = 0;
struct COR_DEBUG_IL_TO_NATIVE_MAP
{
@ -1082,7 +1222,7 @@ namespace VisualPascalABC
public void DoInPausedState(MethodInvoker action)
{
Debugger.Process process = debuggedProcess;
/*Debugger.Process process = debuggedProcess;
if (process.IsPaused)
{
//System.Threading.Thread th = new System.Threading.Thread(new System.Threading.ThreadStart(delegate{action();}));
@ -1098,7 +1238,8 @@ namespace VisualPascalABC
process.DebuggingPaused -= onDebuggingPaused;
};
process.DebuggingPaused += onDebuggingPaused;
}
}*/
action();
}
private NamedValue GetVariableFromName(string variableName)
@ -1271,6 +1412,85 @@ namespace VisualPascalABC
NamedValue global_nv = null;
NamedValue disp_nv = null;
NamedValue ret_nv = null;
Mono.Debugging.Client.ObjectValue global_lv = null;
Mono.Debugging.Client.ObjectValue disp_lv = null;
Mono.Debugging.Client.ObjectValue ret_lv = null;
List<Mono.Debugging.Client.ObjectValue> unit_lvs = new List<Mono.Debugging.Client.ObjectValue>();
var lvc = stackFrame.GetAllLocals();
foreach (var lv in lvc)
if (lv.Name == var)
return new ValueItem(lv);
foreach (var lv in lvc)
{
if (lv.Name.IndexOf(':') != -1)
{
int pos = lv.Name.IndexOf(':');
string name = lv.Name.Substring(0, pos);
if (string.Compare(name, var, true) == 0)
{
int start_line = Convert.ToInt32(lv.Name.Substring(pos + 1, lv.Name.LastIndexOf(':') - pos - 1));
int end_line = Convert.ToInt32(lv.Name.Substring(lv.Name.LastIndexOf(':') + 1));
if (num_line >= start_line - 1 && num_line <= end_line - 1)
return new ValueItem(lv);
}
}
if (string.Compare(lv.Name, var, true) == 0)
{
return new ValueItem(lv);
}
else if (string.Compare(lv.Name, "self", true) == 0 && stackFrame.GetThisReference() != null)
return new ValueItem(stackFrame.GetThisReference());
else if (lv.Name.Contains("$class_var")) global_lv = lv;
else if (lv.Name.Contains("$unit_var")) unit_lvs.Add(lv);
else if (lv.Name == "$disp$") disp_lv = lv;//vo vlozhennyh procedurah ssylka na verh zapis aktivacii
else if (lv.Name.StartsWith("$rv")) ret_lv = lv;//vozvrashaemoe znachenie
}
lvc = stackFrame.GetParameters();
Mono.Debugging.Client.ObjectValue self_lv = null;
foreach (var lv in lvc)
{
if (string.Compare(lv.Name, var, true) == 0)
return new ValueItem(lv);
if (lv.Name == "$obj$")
self_lv = lv;
}
if (var.ToLower() == "self")
{
try
{
return new ValueItem(stackFrame.GetThisReference());
}
catch
{
if (self_lv != null)
return new ValueItem(self_lv);
}
}
if (disp_lv != null)//prohodimsja po vlozhennym podprogrammam
{
Mono.Debugging.Client.ObjectValue parent_val = null;
var fields = disp_lv.GetAllChildren();
foreach (var fi in fields)
if (string.Compare(fi.Name, var, true) == 0)
return new ValueItem(fi);
else if (fi.Name == "$parent$")
parent_val = fi;
var pv = parent_val;
while (!pv.IsNull)
{
fields = parent_val.GetAllChildren();
foreach (var fi in fields)
if (string.Compare(fi.Name, var, true) == 0)
return new ValueItem(fi);
else if (fi.Name == "$parent$")
pv = fi;
if (!pv.IsNull)
parent_val = pv;
}
}
nvc = debuggedProcess.SelectedFunction.LocalVariables;
List<NamedValue> val_list = new List<NamedValue>();
foreach (NamedValue nv in nvc)//smotrim sredi lokalnyh peremennyh
@ -1455,7 +1675,7 @@ namespace VisualPascalABC
}
catch (System.Exception e)
{
Console.WriteLine(e.Message + " "+ e.StackTrace);
}
return null;
}
@ -1493,8 +1713,8 @@ namespace VisualPascalABC
DebuggerGridControl toolTipControl = null;
TextMarker marker = null;
//RemoveMarker((sender as TextArea).Document);
if (debuggedProcess == null) return;
if (debuggedProcess.SelectedFunction == null || !debuggedProcess.IsPaused) return;
if (stackFrame == null)
return;
try
{
TextArea textArea = (TextArea)sender;
@ -1673,7 +1893,7 @@ namespace VisualPascalABC
try
{
workbench.WidgetController.SetStartDebugDisabled();
if (debuggedProcess.SelectedFunction.Name == ".cctor")
/*if (monoDebuggerSession.ActiveThread.Backtrace.GetFrame(0).SourceLocation.MethodName == ".cctor")
{
var sequencePoints = debuggedProcess.SelectedFunction.symMethod.SequencePoints;
if (sequencePoints != null && debuggedProcess.NextStatement.StartLine == sequencePoints[sequencePoints.Length-1].Line)
@ -1684,11 +1904,14 @@ namespace VisualPascalABC
debuggedProcess.StepOver();
}
else
debuggedProcess.StepOver();
debuggedProcess.StepOver();*/
CurrentLineBookmark.Remove();
monoDebuggerSession.NextLine();
}
catch (System.Exception e)
{
Console.WriteLine(e.Message);
}
}
@ -1701,11 +1924,12 @@ namespace VisualPascalABC
try
{
workbench.WidgetController.SetStartDebugDisabled();
dbg.Processes[0].Continue();
monoDebuggerSession.Continue();
CurrentLineBookmark.Remove();
}
catch (System.Exception e)
{
Console.WriteLine(e.Message);
}
}
@ -1718,12 +1942,13 @@ namespace VisualPascalABC
try
{
workbench.WidgetController.SetStartDebugDisabled();
stepin_stmt = dbg.Processes[0].NextStatement;
dbg.Processes[0].StepInto();
stepin_stmt = monoDebuggerSession.ActiveThread.Backtrace.GetFrame(0).SourceLocation;
monoDebuggerSession.StepLine();
CurrentLineBookmark.Remove();
}
catch (System.Exception e)
{
Console.WriteLine(e.Message);
}
}

View file

@ -453,6 +453,8 @@ namespace VisualPascalABC
class ValueItem : ListItem
{
Value val;
Mono.Debugging.Client.ObjectValue monoValue;
public DebugType declaringType;
public ValueItem() {}
@ -462,10 +464,10 @@ namespace VisualPascalABC
[HandleProcessCorruptedStateExceptionsAttribute]
get
{
try
{
bool b = val.IsObject;
return false;
return monoValue.IsPrimitive;
}
catch (System.Exception e)
{
@ -503,6 +505,7 @@ namespace VisualPascalABC
[HandleProcessCorruptedStateExceptionsAttribute]
get
{
return 1;
if (!(val is NamedValue)) return 1;
if (imageIndex != -1) return imageIndex;
if (declaringType == null) return 1;
@ -603,8 +606,12 @@ namespace VisualPascalABC
[HandleProcessCorruptedStateExceptionsAttribute]
get
{
try
{
if (monoValue.Name.IndexOf(':') != -1)
return monoValue.Name.Substring(0, monoValue.Name.IndexOf(':'));
return monoValue.Name;
if (!string.IsNullOrEmpty(name))
return name;
if (!((val is NamedValue) ? (val as NamedValue).Name : name).Contains("$rv"))
@ -661,6 +668,7 @@ namespace VisualPascalABC
[HandleProcessCorruptedStateExceptionsAttribute]
get
{
return monoValue.DisplayValue;
if (ShowValuesInHexadecimal && val.IsInteger)
{
return String.Format("0x{0:X}", val.PrimitiveValue);
@ -785,14 +793,7 @@ namespace VisualPascalABC
{
try
{
if (val.Type != null)
{
return DebugUtils.WrapTypeName(val.Type);
}
else
{
return String.Empty;
}
return monoValue.TypeName;
}
catch(System.Exception e)
{
@ -805,7 +806,7 @@ namespace VisualPascalABC
{
try
{
return val.IsObject;
return monoValue.IsObject;
}
catch (System.Exception e)
{
@ -820,8 +821,11 @@ namespace VisualPascalABC
{
try
{
if (IsEnum() || val.Type.ManagedType == typeof(string)) return false;
return val.IsObject || val.IsArray;
if (monoValue.TypeName == "string")
return false;
return monoValue.IsObject || monoValue.IsArray;
//if (IsEnum() || val.Type.ManagedType == typeof(string)) return false;
//return val.IsObject || val.IsArray;
}
catch (System.Exception e)
{
@ -942,12 +946,18 @@ namespace VisualPascalABC
}
val.Changed += delegate { OnChanged(new ListItemEventArgs(this)); };
}
public ValueItem(Mono.Debugging.Client.ObjectValue val)
{
this.monoValue = val;
}
[HandleProcessCorruptedStateExceptionsAttribute]
public override bool SetText(string newValue)
{
try
{
val.PrimitiveValue = newValue;
monoValue.SetValue(newValue);
return true;
}
catch (NotSupportedException)

View file

@ -439,6 +439,7 @@ namespace Mono.Debugging.Client
OnRunning ();
OnRun (startInfo);
} catch (Exception ex) {
Console.WriteLine(ex.Message+" "+ex.StackTrace);
// should handle exception before raising Exit event because HandleException may ignore exceptions in Exited state
var exceptionHandled = HandleException (ex);
ForceExit ();
@ -1058,7 +1059,7 @@ namespace Mono.Debugging.Client
}
readonly Dictionary<string, IExpressionEvaluator> evaluators = new Dictionary<string, IExpressionEvaluator> ();
readonly ExpressionEvaluator defaultResolver;
readonly ExpressionEvaluator defaultResolver = new ExpressionEvaluator();
internal IExpressionEvaluator FindExpressionEvaluator (StackFrame frame)
{

View file

@ -64,12 +64,12 @@ namespace Mono.Debugger.Soft
VirtualMachine vm = new VirtualMachine (p, conn);
if (info.RedirectStandardOutput)
if (info.RedirectStandardOutput && false)
vm.StandardOutput = p.StandardOutput;
if (info.RedirectStandardError)
if (info.RedirectStandardError && false)
vm.StandardError = p.StandardError;
conn.EventHandler = new EventHandler (vm);
vm.connect ();
@ -82,6 +82,8 @@ namespace Mono.Debugger.Soft
return BeginLaunch (info, callback, null);
}
public static ITargetProcess currentProcess;
public static IAsyncResult BeginLaunch (ProcessStartInfo info, AsyncCallback callback, LaunchOptions options)
{
if (info == null)
@ -103,25 +105,33 @@ namespace Mono.Debugger.Soft
if (options != null && options.Valgrind)
info.FileName = "valgrind";
info.UseShellExecute = false;
info.RedirectStandardError = true;
if (info.RedirectStandardError)
info.StandardErrorEncoding = Encoding.UTF8;
if (info.RedirectStandardOutput)
info.StandardOutputEncoding = Encoding.UTF8;
info.RedirectStandardInput = true;
ITargetProcess p;
if (options != null && options.CustomProcessLauncher != null)
p = new ProcessWrapper (options.CustomProcessLauncher (info));
else if (options != null && options.CustomTargetProcessLauncher != null)
p = options.CustomTargetProcessLauncher (info);
else
p = new ProcessWrapper (Process.Start (info));
{
var netProcess = new System.Diagnostics.Process();
netProcess.StartInfo = info;
netProcess.EnableRaisingEvents = true;
netProcess.Start();
p = new ProcessWrapper(netProcess);
}
p.Exited += delegate (object sender, EventArgs eargs) {
socket.Close ();
};
currentProcess = p;
var listenTask = LaunchInternalAsync (p, info, socket);
listenTask.ContinueWith (t => callback (listenTask));
return listenTask;
@ -347,8 +357,8 @@ namespace Mono.Debugger.Soft
{
VirtualMachine vm = new VirtualMachine (null, transport);
vm.StandardOutput = standardOutput;
vm.StandardError = standardError;
//vm.StandardOutput = standardOutput;
//vm.StandardError = standardError;
transport.EventHandler = new EventHandler (vm);

View file

@ -261,7 +261,6 @@ namespace Mono.Debugging.Evaluation
var ctx = GetEvaluationContext (frameIndex, options);
if (ctx == null)
return null;
finfo = new FrameInfo ();
finfo.Context = ctx;
//Don't try to optimize lines below with lazy loading, you won't gain anything(in communication with runtime)

View file

@ -33,7 +33,20 @@ namespace Mono.Debugging.Evaluation
{
public class EvaluationContext
{
public ExpressionEvaluator Evaluator { get; set; }
private ExpressionEvaluator evaluator;
public ExpressionEvaluator Evaluator {
get
{
if (evaluator == null)
evaluator = new ExpressionEvaluator();
return evaluator;
}
set
{
evaluator = value;
}
}
public ObjectValueAdaptor Adapter { get; set; }
public EvaluationOptions Options {

View file

@ -36,8 +36,13 @@ using Mono.Debugging.Client;
namespace Mono.Debugging.Evaluation
{
public abstract class ExpressionEvaluator
public class ExpressionEvaluator
{
public ExpressionEvaluator()
{
}
public ValueReference Evaluate (EvaluationContext ctx, string expression)
{
return Evaluate (ctx, expression, null);
@ -183,7 +188,10 @@ namespace Mono.Debugging.Evaluation
get { return true; }
}
public abstract string Resolve (DebuggerSession session, SourceLocation location, string expression);
public string Resolve (DebuggerSession session, SourceLocation location, string expression)
{
return expression;
}
public virtual IEnumerable<ValueReference> GetLocalVariables (EvaluationContext ctx)
{

View file

@ -187,11 +187,12 @@ namespace Mono.Debugging.Soft
Arguments = string.Format ("{2} \"{0}\" {1}", dsi.Command, dsi.Arguments, dsi.RuntimeArguments),
WorkingDirectory = dsi.WorkingDirectory,
RedirectStandardOutput = true,
RedirectStandardInput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true,
};
Console.WriteLine(psi.Arguments);
LaunchOptions options = null;
if (dsi.UseExternalConsole && args.ExternalConsoleLauncher != null) {
@ -409,6 +410,11 @@ namespace Mono.Debugging.Soft
}
}
public void ForceEndSession()
{
EndSession();
}
const string StartWithShellExecuteExMarker = "___Process_StartWithShellExecuteEx_Marker___";
const string StartWithCreateProcessMarker = "___Process_StartWithCreateProcess_Marker__";
const string SetProcessIdMarker = "___Process_SetProcessId_Marker__";

View file

@ -193,7 +193,7 @@ namespace VisualPascalABC
{
DebuggerManager.ShowDebugTabs = true;
DebuggerManager.UpdateBreakpoints();
DebuggerManager.CurrentBreakpoint = DebuggerManager.AddBreakPoint(DocumentService.CurrentCodeFileDocument.FileName, DocumentService.CurrentCodeFileDocument.TextEditor.ActiveTextAreaControl.Caret.Line + 1, false);
//DebuggerManager.CurrentBreakpoint = DebuggerManager.AddBreakPoint(DocumentService.CurrentCodeFileDocument.FileName, DocumentService.CurrentCodeFileDocument.TextEditor.ActiveTextAreaControl.Caret.Line + 1, false);
DebuggerManager.AddGoToBreakPoint(DebuggerManager.CurrentBreakpoint);
}
else if (needFirstBreakpoint)
@ -230,7 +230,7 @@ namespace VisualPascalABC
{
// SSM 22/04/19 - исправляю вылет оболочки при отсутствии exe файла
// this.RunnerManager_Exited(OutputFileName); // - это всё равно не срабатывает. Кнопки оказываются в заблокированном состоянии
Console.WriteLine(e.Message+" "+e.StackTrace);
WorkbenchServiceFactory.OperationsService.AddTextToOutputWindowSync(OutputFileName, "Произошла непредвиденная ошибка. Вероятно, на диске отсутствует .exe-файл. Повторите запуск");
//throw;
return false;

View file

@ -496,6 +496,8 @@ namespace VisualPascalABC
public void SetDisassemblyMenuVisible(bool flag)
{
if (tsDisassembly == null)
return;
tsDisassembly.Visible = flag;
}
@ -631,6 +633,8 @@ namespace VisualPascalABC
private bool watch_vis = false;
public void SetDebugTabsVisible(bool flag)
{
if (DebugWatchListWindow == null)
return;
if (flag)
{
if (!DebugWatchListWindow.IsHidden)

View file

@ -656,6 +656,8 @@ namespace VisualPascalABC
public void ClearWatch()
{
if (DebugWatchListWindow == null)
return;
for (int i = 0; i < this.WdataGridView1.Rows.Count; i++)
{
DebugWatchListWindow.SetUndefinedValue(i);
@ -664,7 +666,8 @@ namespace VisualPascalABC
public void DisplayDisassembledCode(string code)
{
DisassemblyWindow.SetDisassembledCode(code);
if (DisassemblyWindow != null)
DisassemblyWindow.SetDisassembledCode(code);
}
public void ClearDebugTabs()
@ -678,7 +681,8 @@ namespace VisualPascalABC
public void ClearLocalVarTree()
{
DebugVariablesListWindow.ClearAllSubTrees();
if (DebugVariablesListWindow != null)
DebugVariablesListWindow.ClearAllSubTrees();
}
public void RefreshPad(IList<IListItem> items)