mirror of https://gitlab.com/basile.b/dexed.git
debugger: only use the central BP database
debugger: parses internal GDB messages as CLI
This commit is contained in:
parent
3e20fc1f88
commit
84f9988c72
|
@ -10,6 +10,7 @@ uses
|
|||
type
|
||||
|
||||
TBreakPointKind = (
|
||||
bpkNone, // nothing
|
||||
bpkBreak, // break point
|
||||
bpkWatch // watch point
|
||||
);
|
||||
|
@ -21,6 +22,7 @@ type
|
|||
function running: boolean;
|
||||
procedure addBreakPoint(const fname: string; line: integer; kind: TBreakPointKind = bpkBreak);
|
||||
procedure removeBreakPoint(const fname: string; line: integer; kind: TBreakPointKind = bpkBreak);
|
||||
procedure removeBreakPoints(const fname: string);
|
||||
end;
|
||||
|
||||
// Enumerates th e reason why debuging breaks.
|
||||
|
@ -40,11 +42,6 @@ type
|
|||
procedure debugStart(debugger: ICEDebugger);
|
||||
// a debugging session terminates. Any pointer to a ICEDebugger becomes invalid.
|
||||
procedure debugStop;
|
||||
// the debuger wants to know how many times debugQueryBreakPoints must be called.
|
||||
function debugQueryBpCount: integer;
|
||||
// the debuger wants breakpoints.
|
||||
procedure debugQueryBreakPoint(const index: integer; out fname: string;
|
||||
out line: integer; out kind: TBreakPointKind);
|
||||
// a break happens when code in fname at line is executed.
|
||||
procedure debugBreak(const fname: string; line: integer; reason: TCEDebugBreakReason);
|
||||
// debugging continue
|
||||
|
|
102
src/ce_gdb.pas
102
src/ce_gdb.pas
|
@ -444,6 +444,8 @@ type
|
|||
protected
|
||||
procedure setToolBarFlat(value: boolean); override;
|
||||
private
|
||||
fSynchronizedDocuments: TStringList;
|
||||
fSynchronizingBreakpoints: boolean;
|
||||
fSyms: ICESymStringExpander;
|
||||
fExe: string;
|
||||
fOutputName: string;
|
||||
|
@ -485,9 +487,7 @@ type
|
|||
procedure updateButtonsState;
|
||||
procedure startDebugging;
|
||||
procedure killGdb;
|
||||
procedure storeObserversBreakpoints;
|
||||
procedure updateDebugeeOptionsEditor;
|
||||
procedure synchronizeBreakpointsFromDoc;
|
||||
procedure deleteRedirectedIO;
|
||||
// GDB output processors
|
||||
procedure gdboutQuiet(sender: TObject);
|
||||
|
@ -525,6 +525,7 @@ type
|
|||
kind: TBreakPointKind = bpkBReak);
|
||||
procedure removeBreakPoint(const fname: string; line: integer;
|
||||
kind: TBreakPointKind = bpkBreak);
|
||||
procedure removeBreakPoints(const fname: string);
|
||||
procedure executeFromShortcut(sender: TObject);
|
||||
public
|
||||
constructor create(aOwner: TComponent); override;
|
||||
|
@ -1173,6 +1174,7 @@ begin
|
|||
Edit1.Items.Assign(fOptions.commandsHistory);
|
||||
fAddWatchPointKind := wpkWrite;
|
||||
fBreakPoints := TPersistentBreakPoints.create(self);
|
||||
fSynchronizedDocuments := TStringList.Create;
|
||||
|
||||
TCEListViewCopyMenu.create(lstCallStack);
|
||||
TCEListViewCopyMenu.create(lstAsm);
|
||||
|
@ -1195,6 +1197,7 @@ begin
|
|||
fInspState.Free;
|
||||
fJson.Free;
|
||||
fStackItems.Free;
|
||||
fSynchronizedDocuments.Free;
|
||||
EntitiesConnector.removeObserver(self);
|
||||
fSubj.free;
|
||||
inherited;
|
||||
|
@ -1406,11 +1409,22 @@ begin
|
|||
end;
|
||||
|
||||
procedure TCEGdbWidget.docFocused(document: TCESynMemo);
|
||||
var
|
||||
i: integer;
|
||||
b: TPersistentBreakPoint;
|
||||
begin
|
||||
fDoc := document;
|
||||
if fGdbState = gsNone then
|
||||
updateDebugeeOptionsEditor;
|
||||
synchronizeBreakpointsFromDoc;
|
||||
fSynchronizingBreakpoints:= true;
|
||||
if fSynchronizedDocuments.IndexOf(document.fileName) = -1 then
|
||||
for i:= 0 to fBreakPoints.count-1 do
|
||||
begin
|
||||
b := fBreakPoints.item[i];
|
||||
if b.filename = fDoc.fileName then
|
||||
fDoc.addBreakpoint(b.line);
|
||||
end;
|
||||
fSynchronizingBreakpoints:= false;
|
||||
end;
|
||||
|
||||
procedure TCEGdbWidget.docChanged(document: TCESynMemo);
|
||||
|
@ -1418,9 +1432,14 @@ begin
|
|||
end;
|
||||
|
||||
procedure TCEGdbWidget.docClosing(document: TCESynMemo);
|
||||
var
|
||||
i: integer;
|
||||
begin
|
||||
if fDoc <> document then
|
||||
exit;
|
||||
i := fSynchronizedDocuments.IndexOf(fDoc.fileName);
|
||||
if i <> -1 then
|
||||
fSynchronizedDocuments.delete(i);
|
||||
fDoc := nil;
|
||||
if fGdbState = gsNone then
|
||||
updateDebugeeOptionsEditor;
|
||||
|
@ -1451,25 +1470,6 @@ begin
|
|||
updateDebugeeOptionsEditor;
|
||||
end;
|
||||
|
||||
procedure TCEGdbWidget.storeObserversBreakpoints;
|
||||
var
|
||||
i,j: integer;
|
||||
obs: ICEDebugObserver;
|
||||
nme: string;
|
||||
lne: integer;
|
||||
knd: TBreakPointKind;
|
||||
begin
|
||||
for i:= 0 to fSubj.observersCount-1 do
|
||||
begin
|
||||
obs := fSubj.observers[i] as ICEDebugObserver;
|
||||
for j := 0 to obs.debugQueryBpCount-1 do
|
||||
begin
|
||||
obs.debugQueryBreakPoint(j, nme, lne, knd);
|
||||
fBreakPoints.addItem(nme, lne, knd);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TCEGdbWidget.waitCommandProcessed;
|
||||
var
|
||||
i: integer = 0;
|
||||
|
@ -1489,6 +1489,8 @@ var
|
|||
r: boolean;
|
||||
a: boolean = false;
|
||||
begin
|
||||
if fSynchronizingBreakpoints then
|
||||
exit;
|
||||
if assigned(fBreakPoints) then
|
||||
a := fBreakPoints.addItem(fname, line, kind);
|
||||
if not a or fGdb.isNil or not fGdb.Running then
|
||||
|
@ -1537,6 +1539,11 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure TCEGdbWidget.removeBreakPoints(const fname: string);
|
||||
begin
|
||||
fBreakPoints.clearFile(fname);
|
||||
end;
|
||||
|
||||
procedure TCEGdbWidget.setState(value: TGdbState);
|
||||
begin
|
||||
if fGdbState = value then
|
||||
|
@ -1713,7 +1720,6 @@ begin
|
|||
fGdb.OnTerminate:= @gdboutJsonize;
|
||||
fgdb.execute;
|
||||
// file:line breakpoints
|
||||
storeObserversBreakpoints;
|
||||
for i:= 0 to fBreakPoints.Count-1 do
|
||||
begin
|
||||
b := fBreakPoints[i];
|
||||
|
@ -1806,46 +1812,6 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure TCEGdbWidget.synchronizeBreakpointsFromDoc;
|
||||
var
|
||||
i: integer;
|
||||
c: integer;
|
||||
j: integer;
|
||||
l: integer;
|
||||
k: TBreakPointKind;
|
||||
s: string;
|
||||
b: boolean;
|
||||
f: ICEDebugObserver;
|
||||
begin
|
||||
if fDoc.isNil then
|
||||
exit;
|
||||
f := fDoc as ICEDebugObserver;
|
||||
if not assigned(f) then
|
||||
exit;
|
||||
c := f.debugQueryBpCount;
|
||||
if c <> 0 then
|
||||
begin
|
||||
for i := fBreakPoints.count-1 downto 0 do
|
||||
begin
|
||||
b := false;
|
||||
if not (fBreakPoints[i].filename = fDoc.fileName) then
|
||||
continue;
|
||||
for j := 0 to c-1 do
|
||||
begin
|
||||
f.debugQueryBreakPoint(j, s, l, k);
|
||||
if l = fBreakPoints[i].line then
|
||||
begin
|
||||
b := true;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
if not b then
|
||||
fBreakPoints.items.Delete(i);
|
||||
end;
|
||||
end
|
||||
else fBreakPoints.clearFile(fDoc.fileName);
|
||||
end;
|
||||
|
||||
procedure TCEGdbWidget.deleteRedirectedIO;
|
||||
begin
|
||||
if fOptions.keepRedirectedStreams then
|
||||
|
@ -2043,9 +2009,7 @@ begin
|
|||
// internal gdb messages
|
||||
'&':
|
||||
begin
|
||||
rng.popUntil(#10);
|
||||
if not rng.empty then
|
||||
rng.popFront;
|
||||
parseCLI(json, rng.popFront);
|
||||
end;
|
||||
// async notify / status / out stream when remote (@)
|
||||
'=', '+','@':
|
||||
|
@ -2243,6 +2207,7 @@ begin
|
|||
subjDebugStop(fSubj);
|
||||
deleteRedirectedIO;
|
||||
updateDebugeeOptionsEditor;
|
||||
killGdb;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -2428,7 +2393,7 @@ begin
|
|||
fShowFromCustomCommand := false;
|
||||
if fJson.findArray('CLI', arr) then
|
||||
for i := 0 to arr.Count-1 do
|
||||
fMsg.message(arr.Strings[i], nil, amcMisc, amkBub);
|
||||
fMsg.message(arr.Strings[i], nil, amcMisc, amkAuto);
|
||||
end;
|
||||
|
||||
end;
|
||||
|
@ -2518,7 +2483,7 @@ end;
|
|||
|
||||
procedure TCEGdbWidget.infoVariables;
|
||||
begin
|
||||
gdbCommand('-stack-list-variables --skip-unavailable --simple-values');
|
||||
gdbCommand('-stack-list-variables --skip-unavailable --all-values');
|
||||
end;
|
||||
|
||||
procedure TCEGdbWidget.infoThreads;
|
||||
|
@ -2604,6 +2569,7 @@ begin
|
|||
setState(gsNone);
|
||||
deleteRedirectedIO;
|
||||
updateDebugeeOptionsEditor;
|
||||
killGdb;
|
||||
end;
|
||||
|
||||
procedure TCEGdbWidget.btnWatchClick(Sender: TObject);
|
||||
|
|
|
@ -82,8 +82,6 @@ type
|
|||
fFontSize: Integer;
|
||||
fSourceFilename: string;
|
||||
procedure setFolds(someFolds: TCollection);
|
||||
procedure writeBreakpoints(str: TStream);
|
||||
procedure readBreakpoints(str: TStream);
|
||||
published
|
||||
property caretPosition: Integer read fCaretPosition write fCaretPosition;
|
||||
property sourceFilename: string read fSourceFilename write fSourceFilename;
|
||||
|
@ -93,8 +91,6 @@ type
|
|||
public
|
||||
constructor create(aComponent: TComponent); override;
|
||||
destructor destroy; override;
|
||||
procedure DefineProperties(Filer: TFiler); override;
|
||||
//
|
||||
procedure beforeSave; override;
|
||||
procedure afterLoad; override;
|
||||
procedure save;
|
||||
|
@ -204,7 +200,6 @@ type
|
|||
fD2Highlighter: TSynD2Syn;
|
||||
fTxtHighlighter: TSynTxtSyn;
|
||||
fImages: TImageList;
|
||||
fBreakPoints: TFPList;
|
||||
fMatchSelectionOpts: TSynSearchOptions;
|
||||
fMatchIdentOpts: TSynSearchOptions;
|
||||
fMatchOpts: TIdentifierMatchOptions;
|
||||
|
@ -282,18 +277,15 @@ type
|
|||
procedure patchClipboardIndentation;
|
||||
//
|
||||
procedure gutterClick(Sender: TObject; X, Y, Line: integer; mark: TSynEditMark);
|
||||
procedure addBreakPoint(line: integer);
|
||||
procedure removeBreakPoint(line: integer);
|
||||
procedure removeDebugTimeMarks;
|
||||
function findBreakPoint(line: integer): boolean;
|
||||
procedure debugStart(debugger: ICEDebugger);
|
||||
procedure debugStop;
|
||||
procedure debugContinue;
|
||||
function debugQueryBpCount: integer;
|
||||
procedure debugQueryBreakPoint(const index: integer; out fname: string; out line: integer; out kind: TBreakPointKind);
|
||||
procedure debugQueryBreakPoint(const line: integer; out fname: string; out kind: TBreakPointKind);
|
||||
procedure debugBreak(const fname: string; line: integer; reason: TCEDebugBreakReason);
|
||||
function breakPointsCount: integer;
|
||||
function breakPointLine(index: integer): integer;
|
||||
protected
|
||||
procedure DoEnter; override;
|
||||
procedure DoExit; override;
|
||||
|
@ -322,6 +314,8 @@ type
|
|||
procedure save;
|
||||
procedure saveTempFile;
|
||||
//
|
||||
procedure addBreakPoint(line: integer);
|
||||
procedure removeBreakPoint(line: integer);
|
||||
procedure curlyBraceCloseAndIndent;
|
||||
procedure insertLeadingDDocSymbol(c: char);
|
||||
procedure commentSelection;
|
||||
|
@ -576,42 +570,11 @@ begin
|
|||
inherited;
|
||||
end;
|
||||
|
||||
procedure TCESynMemoCache.DefineProperties(Filer: TFiler);
|
||||
begin
|
||||
inherited;
|
||||
Filer.DefineBinaryProperty('breakpoints', @readBreakpoints, @writeBreakpoints, true);
|
||||
end;
|
||||
|
||||
procedure TCESynMemoCache.setFolds(someFolds: TCollection);
|
||||
begin
|
||||
fFolds.Assign(someFolds);
|
||||
end;
|
||||
|
||||
procedure TCESynMemoCache.writeBreakpoints(str: TStream);
|
||||
var
|
||||
i: integer;
|
||||
begin
|
||||
if fMemo.isNil then exit;
|
||||
{$HINTS OFF}
|
||||
for i:= 0 to fMemo.fBreakPoints.Count-1 do
|
||||
str.Write(PtrUint(fMemo.fBreakPoints.Items[i]), sizeOf(PtrUint));
|
||||
{$HINTS ON}
|
||||
end;
|
||||
|
||||
procedure TCESynMemoCache.readBreakpoints(str: TStream);
|
||||
var
|
||||
i, cnt: integer;
|
||||
line: ptrUint = 0;
|
||||
begin
|
||||
if fMemo.isNil then exit;
|
||||
cnt := str.Size div sizeOf(PtrUint);
|
||||
for i := 0 to cnt-1 do
|
||||
begin
|
||||
str.Read(line, sizeOf(line));
|
||||
fMemo.addBreakPoint(line);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TCESynMemoCache.beforeSave;
|
||||
var
|
||||
i, start, prev: Integer;
|
||||
|
@ -941,7 +904,6 @@ begin
|
|||
fImages.AddResourceName(HINSTANCE, 'STEP');
|
||||
fImages.AddResourceName(HINSTANCE, 'CAMERA_GO');
|
||||
fImages.AddResourceName(HINSTANCE, 'WARNING');
|
||||
fBreakPoints := TFPList.Create;
|
||||
|
||||
fPositions := TCESynMemoPositions.create(self);
|
||||
fMultiDocSubject := TCEMultiDocSubject.create;
|
||||
|
@ -978,7 +940,6 @@ begin
|
|||
fMultiDocSubject.Free;
|
||||
fPositions.Free;
|
||||
fCompletion.Free;
|
||||
fBreakPoints.Free;
|
||||
fCallTipStrings.Free;
|
||||
fLexToks.Clear;
|
||||
fLexToks.Free;
|
||||
|
@ -3237,17 +3198,12 @@ end;
|
|||
|
||||
{$REGION debugging/breakpoints -----------------------------------------------------------}
|
||||
function TCESynMemo.breakPointsCount: integer;
|
||||
var
|
||||
i: integer;
|
||||
begin
|
||||
exit(fBreakPoints.Count);
|
||||
end;
|
||||
|
||||
function TCESynMemo.BreakPointLine(index: integer): integer;
|
||||
begin
|
||||
if index >= fBreakPoints.Count then
|
||||
exit(0);
|
||||
{$PUSH}{$WARNINGS OFF}{$HINTS OFF}
|
||||
exit(Integer(fBreakPoints.Items[index]));
|
||||
{$POP}
|
||||
result := 0;
|
||||
for i := 0 to marks.count-1 do
|
||||
result += byte(marks[i].ImageIndex = integer(giBreakSet));
|
||||
end;
|
||||
|
||||
procedure TCESynMemo.addBreakPoint(line: integer);
|
||||
|
@ -3255,9 +3211,6 @@ begin
|
|||
if findBreakPoint(line) then
|
||||
exit;
|
||||
addGutterIcon(line, giBreakSet);
|
||||
{$PUSH}{$WARNINGS OFF}{$HINTS OFF}
|
||||
fBreakPoints.Add(pointer(line));
|
||||
{$POP}
|
||||
if assigned(fDebugger) then
|
||||
fDebugger.addBreakPoint(fFilename, line, bpkBreak);
|
||||
end;
|
||||
|
@ -3267,9 +3220,6 @@ begin
|
|||
if not findBreakPoint(line) then
|
||||
exit;
|
||||
removeGutterIcon(line, giBreakSet);
|
||||
{$PUSH}{$WARNINGS OFF}{$HINTS OFF}
|
||||
fBreakPoints.Remove(pointer(line));
|
||||
{$POP}
|
||||
if assigned(fDebugger) then
|
||||
fDebugger.removeBreakPoint(fFilename, line);
|
||||
end;
|
||||
|
@ -3308,10 +3258,17 @@ begin
|
|||
end;
|
||||
|
||||
function TCESynMemo.findBreakPoint(line: integer): boolean;
|
||||
var
|
||||
m: TSynEditMarkLine;
|
||||
i: integer;
|
||||
begin
|
||||
{$PUSH}{$WARNINGS OFF}{$HINTS OFF}
|
||||
exit(fBreakPoints.IndexOf(pointer(line)) <> -1);
|
||||
{$POP}
|
||||
result := false;
|
||||
if line <= lines.count then
|
||||
m := marks.Line[line];
|
||||
if m.isNotNil then
|
||||
for i := 0 to m.count - 1 do
|
||||
if m[i].ImageIndex = integer(giBreakSet) then
|
||||
exit(true);
|
||||
end;
|
||||
|
||||
procedure TCESynMemo.gutterClick(Sender: TObject; X, Y, Line: integer; mark: TSynEditMark);
|
||||
|
@ -3370,8 +3327,18 @@ begin
|
|||
end;
|
||||
|
||||
procedure TCESynMemo.debugStart(debugger: ICEDebugger);
|
||||
var
|
||||
i: integer;
|
||||
m: TSynEditMark;
|
||||
begin
|
||||
fDebugger := debugger;
|
||||
fDebugger.removeBreakPoints(fileName);
|
||||
for i := 0 to marks.count - 1 do
|
||||
begin
|
||||
m := marks[i];
|
||||
if m.ImageIndex = integer(giBreakSet) then
|
||||
fDebugger.addBreakPoint(filename, m.line, bpkBreak);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TCESynMemo.debugStop;
|
||||
|
@ -3386,15 +3353,17 @@ end;
|
|||
|
||||
function TCESynMemo.debugQueryBpCount: integer;
|
||||
begin
|
||||
exit(fBreakPoints.Count);
|
||||
exit(breakPointsCount());
|
||||
end;
|
||||
|
||||
procedure TCESynMemo.debugQueryBreakPoint(const index: integer; out fname: string;
|
||||
out line: integer; out kind: TBreakPointKind);
|
||||
procedure TCESynMemo.debugQueryBreakPoint(const line: integer; out fname: string; out kind: TBreakPointKind);
|
||||
begin
|
||||
fname:= fFilename;
|
||||
line := breakPointLine(index);
|
||||
kind := bpkBreak;
|
||||
if findBreakPoint(line) then
|
||||
begin
|
||||
fname:= fFilename;
|
||||
kind := bpkBreak;
|
||||
end
|
||||
else kind := bpkNone;
|
||||
end;
|
||||
|
||||
procedure TCESynMemo.debugBreak(const fname: string; line: integer;
|
||||
|
|
Loading…
Reference in New Issue