mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-09-07 16:20:32 +02:00
debugger: implement address breakpoints
git-svn-id: trunk@30673 -
This commit is contained in:
parent
271b185f2c
commit
f805a11b16
@ -135,8 +135,10 @@ inherited BreakpointsDlg: TBreakpointsDlg
|
||||
object popAdd: TMenuItem
|
||||
Caption = 'Add...'
|
||||
object popAddSourceBP: TMenuItem
|
||||
Caption = '&Source breakpoint'
|
||||
Enabled = False
|
||||
Action = actAddSourceBP
|
||||
end
|
||||
object popAddAddressBP: TMenuItem
|
||||
Action = actAddAddressBP
|
||||
end
|
||||
end
|
||||
object N1: TMenuItem
|
||||
@ -224,5 +226,16 @@ inherited BreakpointsDlg: TBreakpointsDlg
|
||||
Caption = 'actProperties'
|
||||
OnExecute = popPropertiesClick
|
||||
end
|
||||
object actAddSourceBP: TAction
|
||||
Category = 'Add'
|
||||
Caption = 'actAddSourceBP'
|
||||
OnExecute = actAddSourceBPExecute
|
||||
ShortCut = 45
|
||||
end
|
||||
object actAddAddressBP: TAction
|
||||
Category = 'Add'
|
||||
Caption = 'actAddAddressBP'
|
||||
OnExecute = actAddAddressBPExecute
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -40,7 +40,7 @@ interface
|
||||
uses
|
||||
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
|
||||
Buttons, Menus, ComCtrls, IDEProcs, Debugger, DebuggerDlg, lclType, ActnList, MainBase,
|
||||
IDEImagesIntf;
|
||||
IDEImagesIntf, SourceEditor;
|
||||
|
||||
type
|
||||
TBreakPointsDlgState = (
|
||||
@ -51,6 +51,8 @@ type
|
||||
{ TBreakPointsDlg }
|
||||
|
||||
TBreakPointsDlg = class(TDebuggerDlg)
|
||||
actAddSourceBP: TAction;
|
||||
actAddAddressBP: TAction;
|
||||
actProperties: TAction;
|
||||
actToggleCurrentEnable: TAction;
|
||||
actDeleteAllInSrc: TAction;
|
||||
@ -64,6 +66,7 @@ type
|
||||
actDisableAllInSrc: TAction;
|
||||
ActionList1: TActionList;
|
||||
lvBreakPoints: TListView;
|
||||
popAddAddressBP: TMenuItem;
|
||||
N0: TMenuItem;
|
||||
popShow: TMenuItem;
|
||||
mnuPopup: TPopupMenu;
|
||||
@ -91,6 +94,8 @@ type
|
||||
ToolButtonEnableAll: TToolButton;
|
||||
ToolButtonDisableAll: TToolButton;
|
||||
ToolButtonTrashAll: TToolButton;
|
||||
procedure actAddAddressBPExecute(Sender: TObject);
|
||||
procedure actAddSourceBPExecute(Sender: TObject);
|
||||
procedure actDisableSelectedExecute(Sender: TObject);
|
||||
procedure actEnableSelectedExecute(Sender: TObject);
|
||||
procedure BreakpointsDlgCREATE(Sender: TObject);
|
||||
@ -344,7 +349,8 @@ begin
|
||||
lvBreakPoints.Columns[6].Caption:= lisGroup;
|
||||
popShow.Caption:= lisShow;
|
||||
popAdd.Caption:= dlgEdAdd;
|
||||
popAddSourceBP.Caption:= lisSourceBreakpoint;
|
||||
actAddSourceBP.Caption:= lisSourceBreakpoint;
|
||||
actAddAddressBP.Caption := listAddressBreakpoint;
|
||||
end;
|
||||
|
||||
procedure TBreakPointsDlg.actEnableSelectedExecute(Sender: TObject);
|
||||
@ -383,6 +389,33 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TBreakPointsDlg.actAddSourceBPExecute(Sender: TObject);
|
||||
var
|
||||
NewBreakpoint: TIDEBreakPoint;
|
||||
SrcEdit: TSourceEditor;
|
||||
begin
|
||||
SrcEdit := SourceEditorManager.GetActiveSE;
|
||||
if SrcEdit <> nil then
|
||||
NewBreakpoint := BreakPoints.Add(SrcEdit.FileName, SrcEdit.CurrentCursorYLine)
|
||||
else
|
||||
NewBreakpoint := BreakPoints.Add('', 0);
|
||||
if DebugBoss.ShowBreakPointProperties(NewBreakpoint) = mrOk then
|
||||
UpdateAll
|
||||
else
|
||||
NewBreakpoint.Free;
|
||||
end;
|
||||
|
||||
procedure TBreakPointsDlg.actAddAddressBPExecute(Sender: TObject);
|
||||
var
|
||||
NewBreakpoint: TIDEBreakPoint;
|
||||
begin
|
||||
NewBreakpoint := BreakPoints.Add(0);
|
||||
if DebugBoss.ShowBreakPointProperties(NewBreakpoint) = mrOk then
|
||||
UpdateAll
|
||||
else
|
||||
NewBreakpoint.Free;
|
||||
end;
|
||||
|
||||
procedure TBreakPointsDlg.lvBreakPointsClick(Sender: TObject);
|
||||
begin
|
||||
lvBreakPointsSelectItem(nil, nil, False);
|
||||
@ -433,7 +466,7 @@ begin
|
||||
if Handled then
|
||||
Key := 0
|
||||
else
|
||||
inherited;;
|
||||
inherited;
|
||||
lvBreakPointsSelectItem(nil, nil, False);
|
||||
end;
|
||||
|
||||
@ -692,6 +725,8 @@ var
|
||||
begin
|
||||
for i := 0 to ActionList1.ActionCount - 1 do
|
||||
(ActionList1.Actions[i] as TAction).Enabled := False;
|
||||
actAddSourceBP.Enabled := True;
|
||||
actAddAddressBP.Enabled := True;
|
||||
end;
|
||||
|
||||
procedure TBreakPointsDlg.UpdateItem(const AnItem: TListItem;
|
||||
@ -709,17 +744,26 @@ begin
|
||||
// state
|
||||
AnItem.Caption := GetBreakPointStateDescription(ABreakpoint);
|
||||
|
||||
// filename
|
||||
Filename:=ABreakpoint.Source;
|
||||
if BaseDirectory<>'' then
|
||||
Filename:=CreateRelativePath(Filename,BaseDirectory);
|
||||
AnItem.SubItems[0] := Filename;
|
||||
|
||||
// line
|
||||
if ABreakpoint.Line > 0
|
||||
then AnItem.SubItems[1] := IntToStr(ABreakpoint.Line)
|
||||
else AnItem.SubItems[1] := '';
|
||||
|
||||
// filename/address
|
||||
case ABreakpoint.Kind of
|
||||
bpkSource:
|
||||
begin
|
||||
Filename:=ABreakpoint.Source;
|
||||
if BaseDirectory<>'' then
|
||||
Filename:=CreateRelativePath(Filename,BaseDirectory);
|
||||
AnItem.SubItems[0] := Filename;
|
||||
// line
|
||||
if ABreakpoint.Line > 0
|
||||
then AnItem.SubItems[1] := IntToStr(ABreakpoint.Line)
|
||||
else AnItem.SubItems[1] := '';
|
||||
end;
|
||||
bpkAddress:
|
||||
begin
|
||||
// todo: how to define digits count? 8 or 16 depends on gdb pointer size for platform
|
||||
AnItem.SubItems[0] := '$' + IntToHex(ABreakpoint.Address, 8);
|
||||
end;
|
||||
end;
|
||||
|
||||
// expression
|
||||
AnItem.SubItems[2] := ABreakpoint.Expression;
|
||||
|
||||
@ -809,8 +853,8 @@ begin
|
||||
CurItem:=lvBreakPoints.Selected;
|
||||
if CurItem=nil then exit;
|
||||
CurBreakPoint:=TIDEBreakPoint(CurItem.Data);
|
||||
|
||||
MainIDE.DoJumpToSourcePosition(CurBreakPoint.Source, 0, CurBreakPoint.Line, 0, True);
|
||||
if CurBreakPoint.Kind = bpkSource then
|
||||
MainIDE.DoJumpToSourcePosition(CurBreakPoint.Source, 0, CurBreakPoint.Line, 0, True);
|
||||
end;
|
||||
|
||||
procedure TBreakPointsDlg.ShowProperties;
|
||||
|
@ -1,6 +1,6 @@
|
||||
inherited BreakPropertyDlg: TBreakPropertyDlg
|
||||
Left = 249
|
||||
Height = 371
|
||||
Height = 398
|
||||
Top = 187
|
||||
Width = 450
|
||||
HorzScrollBar.Page = 386
|
||||
@ -11,7 +11,7 @@ inherited BreakPropertyDlg: TBreakPropertyDlg
|
||||
BorderIcons = [biSystemMenu]
|
||||
BorderStyle = bsDialog
|
||||
Caption = 'Breakpoint Properties'
|
||||
ClientHeight = 371
|
||||
ClientHeight = 398
|
||||
ClientWidth = 450
|
||||
Constraints.MinWidth = 450
|
||||
Position = poScreenCenter
|
||||
@ -30,7 +30,6 @@ inherited BreakPropertyDlg: TBreakPropertyDlg
|
||||
end
|
||||
object lblLine: TLabel[1]
|
||||
AnchorSideLeft.Control = Owner
|
||||
AnchorSideTop.Control = edtLine
|
||||
AnchorSideTop.Side = asrCenter
|
||||
Left = 6
|
||||
Height = 16
|
||||
@ -118,7 +117,7 @@ inherited BreakPropertyDlg: TBreakPropertyDlg
|
||||
Width = 60
|
||||
BorderSpacing.Left = 24
|
||||
BorderSpacing.Around = 6
|
||||
TabOrder = 3
|
||||
TabOrder = 2
|
||||
Text = 'edtAutocontinueMS'
|
||||
end
|
||||
object edtCounter: TEdit[8]
|
||||
@ -135,27 +134,10 @@ inherited BreakPropertyDlg: TBreakPropertyDlg
|
||||
Anchors = [akTop, akLeft, akRight]
|
||||
BorderSpacing.Left = 24
|
||||
BorderSpacing.Around = 6
|
||||
TabOrder = 2
|
||||
TabOrder = 1
|
||||
Text = 'edtCounter'
|
||||
end
|
||||
object edtLine: TEdit[9]
|
||||
AnchorSideLeft.Control = lblAutoContinue
|
||||
AnchorSideLeft.Side = asrBottom
|
||||
AnchorSideTop.Control = edtFilename
|
||||
AnchorSideTop.Side = asrBottom
|
||||
AnchorSideRight.Side = asrBottom
|
||||
Left = 140
|
||||
Height = 23
|
||||
Top = 35
|
||||
Width = 60
|
||||
BorderSpacing.Left = 24
|
||||
BorderSpacing.Around = 6
|
||||
Color = clBtnFace
|
||||
ReadOnly = True
|
||||
TabOrder = 1
|
||||
Text = 'edtLine'
|
||||
end
|
||||
object edtFilename: TEdit[10]
|
||||
object edtFilename: TEdit[9]
|
||||
AnchorSideLeft.Control = lblAutoContinue
|
||||
AnchorSideLeft.Side = asrBottom
|
||||
AnchorSideTop.Control = Owner
|
||||
@ -173,7 +155,7 @@ inherited BreakPropertyDlg: TBreakPropertyDlg
|
||||
TabOrder = 0
|
||||
Text = 'edtFilename'
|
||||
end
|
||||
object cmbGroup: TComboBox[11]
|
||||
object cmbGroup: TComboBox[10]
|
||||
AnchorSideLeft.Control = lblAutoContinue
|
||||
AnchorSideLeft.Side = asrBottom
|
||||
AnchorSideTop.Control = edtAutocontinueMS
|
||||
@ -188,10 +170,10 @@ inherited BreakPropertyDlg: TBreakPropertyDlg
|
||||
BorderSpacing.Left = 24
|
||||
BorderSpacing.Around = 6
|
||||
ItemHeight = 15
|
||||
TabOrder = 4
|
||||
TabOrder = 3
|
||||
Text = 'cmbGroup'
|
||||
end
|
||||
object gbActions: TGroupBox[12]
|
||||
object gbActions: TGroupBox[11]
|
||||
AnchorSideLeft.Control = Owner
|
||||
AnchorSideTop.Control = cmbGroup
|
||||
AnchorSideTop.Side = asrBottom
|
||||
@ -207,7 +189,7 @@ inherited BreakPropertyDlg: TBreakPropertyDlg
|
||||
Caption = 'Actions'
|
||||
ClientHeight = 147
|
||||
ClientWidth = 434
|
||||
TabOrder = 5
|
||||
TabOrder = 4
|
||||
object chkActionBreak: TCheckBox
|
||||
AnchorSideLeft.Control = gbActions
|
||||
AnchorSideTop.Control = gbActions
|
||||
@ -354,12 +336,11 @@ inherited BreakPropertyDlg: TBreakPropertyDlg
|
||||
TabOrder = 8
|
||||
end
|
||||
end
|
||||
object ButtonPanel: TButtonPanel[13]
|
||||
object ButtonPanel: TButtonPanel[12]
|
||||
AnchorSideTop.Control = gbActions
|
||||
AnchorSideTop.Side = asrBottom
|
||||
AnchorSideRight.Side = asrBottom
|
||||
Left = 6
|
||||
Height = 14
|
||||
Height = 41
|
||||
Top = 351
|
||||
Width = 438
|
||||
Anchors = [akTop, akLeft, akRight, akBottom]
|
||||
@ -374,11 +355,11 @@ inherited BreakPropertyDlg: TBreakPropertyDlg
|
||||
CloseButton.Enabled = False
|
||||
CancelButton.Name = 'CancelButton'
|
||||
CancelButton.Caption = 'Cancel'
|
||||
TabOrder = 6
|
||||
TabOrder = 5
|
||||
ShowButtons = [pbOK, pbCancel, pbHelp]
|
||||
ShowBevel = False
|
||||
end
|
||||
object edtCondition: TComboBox[14]
|
||||
object edtCondition: TComboBox[13]
|
||||
AnchorSideLeft.Control = lblAutoContinue
|
||||
AnchorSideLeft.Side = asrBottom
|
||||
AnchorSideTop.Control = edtLine
|
||||
@ -393,7 +374,22 @@ inherited BreakPropertyDlg: TBreakPropertyDlg
|
||||
BorderSpacing.Left = 24
|
||||
BorderSpacing.Around = 6
|
||||
ItemHeight = 15
|
||||
TabOrder = 7
|
||||
TabOrder = 6
|
||||
Text = 'edtCondition'
|
||||
end
|
||||
object edtLine: TSpinEdit[14]
|
||||
AnchorSideLeft.Control = lblAutoContinue
|
||||
AnchorSideLeft.Side = asrBottom
|
||||
AnchorSideTop.Control = edtFilename
|
||||
AnchorSideTop.Side = asrBottom
|
||||
AnchorSideRight.Side = asrBottom
|
||||
Left = 140
|
||||
Height = 23
|
||||
Top = 35
|
||||
Width = 60
|
||||
BorderSpacing.Left = 24
|
||||
BorderSpacing.Around = 6
|
||||
MaxValue = 999999
|
||||
TabOrder = 7
|
||||
end
|
||||
end
|
||||
|
@ -6,7 +6,7 @@ interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, LCLProc,
|
||||
ExtCtrls, StdCtrls, Buttons, ButtonPanel, EditBtn,
|
||||
ExtCtrls, StdCtrls, Buttons, ButtonPanel, EditBtn, Spin,
|
||||
IDEHelpIntf,
|
||||
DebuggerDlg, Debugger, BaseDebugManager, LazarusIDEStrConsts, InputHistory;
|
||||
|
||||
@ -24,13 +24,13 @@ type
|
||||
cmbGroup: TComboBox;
|
||||
edtCondition: TComboBox;
|
||||
edtEvalExpression: TEdit;
|
||||
edtLine: TSpinEdit;
|
||||
edtLogMessage: TEdit;
|
||||
edtEnableGroups: TEditButton;
|
||||
edtDisableGroups: TEditButton;
|
||||
edtAutocontinueMS: TEdit;
|
||||
edtCounter: TEdit;
|
||||
edtFilename: TEdit;
|
||||
edtLine: TEdit;
|
||||
gbActions: TGroupBox;
|
||||
lblMS: TLabel;
|
||||
lblFileName: TLabel;
|
||||
@ -93,9 +93,17 @@ begin
|
||||
if FBreakpoint = nil then Exit;
|
||||
|
||||
FBreakpointsNotification.OnUpdate := nil;
|
||||
// filename
|
||||
// line
|
||||
FBreakpoint.SetLocation(edtFilename.Text, StrToIntDef(edtLine.Text, 1));
|
||||
case FBreakpoint.Kind of
|
||||
bpkSource:
|
||||
begin
|
||||
// filename + line
|
||||
FBreakpoint.SetLocation(edtFilename.Text, edtLine.Value);
|
||||
end;
|
||||
bpkAddress:
|
||||
begin
|
||||
FBreakpoint.SetAddress(StrToQWordDef(edtFilename.Text, 0));
|
||||
end;
|
||||
end;
|
||||
// expression
|
||||
FBreakpoint.Expression := edtCondition.Text;
|
||||
// hitcount
|
||||
@ -128,12 +136,21 @@ var
|
||||
Actions: TIDEBreakPointActions;
|
||||
begin
|
||||
if FBreakpoint = nil then Exit;
|
||||
// filename
|
||||
edtFilename.text := FBreakpoint.Source;
|
||||
// line
|
||||
if FBreakpoint.Line > 0
|
||||
then edtLine.Text := IntToStr(FBreakpoint.Line)
|
||||
else edtLine.Text := '';
|
||||
case FBreakpoint.Kind of
|
||||
bpkSource:
|
||||
begin
|
||||
// filename
|
||||
edtFilename.Text := FBreakpoint.Source;
|
||||
// line
|
||||
if FBreakpoint.Line > 0
|
||||
then edtLine.Value := FBreakpoint.Line
|
||||
else edtLine.Value := 0;
|
||||
end;
|
||||
bpkAddress:
|
||||
begin
|
||||
edtFilename.Text := '$' + IntToHex(FBreakpoint.Address, 8); // todo: 8/16 depends on platform
|
||||
end;
|
||||
end;
|
||||
// expression
|
||||
edtCondition.Text := FBreakpoint.Expression;
|
||||
// hitcount
|
||||
@ -160,8 +177,21 @@ begin
|
||||
inherited Create(AOwner);
|
||||
|
||||
Caption := lisBreakPointProperties;
|
||||
lblFileName.Caption := lisPEFilename;
|
||||
lblLine.Caption := lisLine;
|
||||
case ABreakPoint.Kind of
|
||||
bpkSource:
|
||||
begin
|
||||
lblFileName.Caption := lisPEFilename;
|
||||
lblLine.Caption := lisLine;
|
||||
end;
|
||||
bpkAddress:
|
||||
begin
|
||||
lblFileName.Caption := lisAddress;
|
||||
lblLine.Visible := False;
|
||||
edtLine.Visible := False;
|
||||
edtFilename.ReadOnly := False;
|
||||
edtFilename.Color := clDefault;
|
||||
end;
|
||||
end;
|
||||
lblCondition.Caption := lisCondition + ':';
|
||||
lblHitCount.Caption := lisHitCount + ':';
|
||||
lblAutoContinue.Caption := lisAutoContinueAfter;
|
||||
|
@ -670,8 +670,9 @@ type
|
||||
TGDBMIDebuggerCommandBreakPointBase = class(TGDBMIDebuggerCommand)
|
||||
protected
|
||||
function ExecBreakDelete(ABreakId: Integer): Boolean;
|
||||
function ExecBreakInsert(ASource: string; ALine: Integer; AEnabled: Boolean;
|
||||
out ABreakId, AHitCnt: Integer; out AnAddr: TDBGPtr): Boolean;
|
||||
function ExecBreakInsert(AKind: TDBGBreakPointKind; AAddress: TDBGPtr;
|
||||
ASource: string; ALine: Integer; AEnabled: Boolean;
|
||||
out ABreakId, AHitCnt: Integer; out AnAddr: TDBGPtr): Boolean;
|
||||
function ExecBreakEnabled(ABreakId: Integer; AnEnabled: Boolean): Boolean;
|
||||
function ExecBreakCondition(ABreakId: Integer; AnExpression: string): Boolean;
|
||||
end;
|
||||
@ -680,13 +681,14 @@ type
|
||||
|
||||
TGDBMIDebuggerCommandBreakInsert = class(TGDBMIDebuggerCommandBreakPointBase)
|
||||
private
|
||||
FKind: TDBGBreakPointKind;
|
||||
FAddress: TDBGPtr;
|
||||
FSource: string;
|
||||
FLine: Integer;
|
||||
FEnabled: Boolean;
|
||||
FExpression: string;
|
||||
FReplaceId: Integer;
|
||||
|
||||
FAddr: TDBGPtr;
|
||||
FBreakID: Integer;
|
||||
FHitCnt: Integer;
|
||||
FValid: Boolean;
|
||||
@ -694,8 +696,12 @@ type
|
||||
function DoExecute: Boolean; override;
|
||||
public
|
||||
constructor Create(AOwner: TGDBMIDebugger; ASource: string; ALine: Integer;
|
||||
AEnabled: Boolean; AnExpression: string; AReplaceId: Integer);
|
||||
AEnabled: Boolean; AnExpression: string; AReplaceId: Integer); overload;
|
||||
constructor Create(AOwner: TGDBMIDebugger; AAddress: TDBGPtr;
|
||||
AEnabled: Boolean; AnExpression: string; AReplaceId: Integer); overload;
|
||||
function DebugText: String; override;
|
||||
property Kind: TDBGBreakPointKind read FKind write FKind;
|
||||
property Address: TDBGPtr read FAddress write FAddress;
|
||||
property Source: string read FSource write FSource;
|
||||
property Line: Integer read FLine write FLine;
|
||||
property Enabled: Boolean read FEnabled write FEnabled;
|
||||
@ -703,7 +709,6 @@ type
|
||||
property ReplaceId: Integer read FReplaceId write FReplaceId;
|
||||
// result values
|
||||
property BreakID: Integer read FBreakID;
|
||||
property Addr: TDBGPtr read FAddr;
|
||||
property HitCnt: Integer read FHitCnt;
|
||||
property Valid: Boolean read FValid;
|
||||
end;
|
||||
@ -765,6 +770,7 @@ type
|
||||
procedure DoExpressionChange; override;
|
||||
procedure DoStateChange(const AOldState: TDBGState); override;
|
||||
procedure MakeInvalid;
|
||||
procedure SetAddress(const AValue: TDBGPtr); override;
|
||||
public
|
||||
constructor Create(ACollection: TCollection); override;
|
||||
destructor Destroy; override;
|
||||
@ -5497,12 +5503,21 @@ procedure TGDBMIDebugger.DoDbgBreakpointEvent(ABreakpoint: TDBGBreakPoint; Locat
|
||||
var
|
||||
SrcName: String;
|
||||
begin
|
||||
SrcName := Location.SrcFullName;
|
||||
if SrcName = '' then
|
||||
SrcName := Location.SrcFile;
|
||||
if SrcName = '' then
|
||||
SrcName := ABreakpoint.Source;
|
||||
DoDbgEvent(ecBreakpoint, etBreakpointHit, Format('Breakpoint at $%.' + IntToStr(TargetPtrSize * 2) + 'x: %s line %d', [Location.Address, SrcName, Location.SrcLine]));
|
||||
case ABreakPoint.Kind of
|
||||
bpkSource:
|
||||
begin
|
||||
SrcName := Location.SrcFullName;
|
||||
if SrcName = '' then
|
||||
SrcName := Location.SrcFile;
|
||||
if SrcName = '' then
|
||||
SrcName := ABreakpoint.Source;
|
||||
DoDbgEvent(ecBreakpoint, etBreakpointHit, Format('Source Breakpoint at $%.' + IntToStr(TargetPtrSize * 2) + 'x: %s line %d', [Location.Address, SrcName, Location.SrcLine]));
|
||||
end;
|
||||
bpkAddress:
|
||||
begin
|
||||
DoDbgEvent(ecBreakpoint, etBreakpointHit, Format('Address Breakpoint at $%.' + IntToStr(TargetPtrSize * 2) + 'x', [Location.Address]));
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TGDBMIDebugger.ExecuteCommand(const ACommand: String;
|
||||
@ -6639,8 +6654,8 @@ begin
|
||||
Result := ExecuteCommand('-break-delete %d', [ABreakID], []);
|
||||
end;
|
||||
|
||||
function TGDBMIDebuggerCommandBreakPointBase.ExecBreakInsert(ASource: string; ALine: Integer;
|
||||
AEnabled: Boolean; out ABreakId, AHitCnt: Integer; out AnAddr: TDBGPtr): Boolean;
|
||||
function TGDBMIDebuggerCommandBreakPointBase.ExecBreakInsert(AKind: TDBGBreakPointKind; AAddress: TDBGPtr;
|
||||
ASource: string; ALine: Integer; AEnabled: Boolean; out ABreakId, AHitCnt: Integer; out AnAddr: TDBGPtr): Boolean;
|
||||
var
|
||||
R: TGDBMIExecResult;
|
||||
ResultList: TGDBMINameValueList;
|
||||
@ -6649,11 +6664,21 @@ begin
|
||||
ABreakId := 0;
|
||||
AHitCnt := 0;
|
||||
AnAddr := 0;
|
||||
If (ASource = '') or (ALine < 0) then exit;
|
||||
|
||||
if dfForceBreak in FTheDebugger.FDebuggerFlags
|
||||
then Result := ExecuteCommand('-break-insert -f %s:%d', [ExtractFileName(ASource), ALine], R)
|
||||
else Result := ExecuteCommand('-break-insert %s:%d', [ExtractFileName(ASource), ALine], R);
|
||||
case AKind of
|
||||
bpkSource:
|
||||
begin
|
||||
if (ASource = '') or (ALine < 0) then exit;
|
||||
if dfForceBreak in FTheDebugger.FDebuggerFlags
|
||||
then Result := ExecuteCommand('-break-insert -f %s:%d', [ExtractFileName(ASource), ALine], R)
|
||||
else Result := ExecuteCommand('-break-insert %s:%d', [ExtractFileName(ASource), ALine], R);
|
||||
end;
|
||||
bpkAddress:
|
||||
begin
|
||||
if dfForceBreak in FTheDebugger.FDebuggerFlags
|
||||
then Result := ExecuteCommand('-break-insert -f *%u', [AAddress], R)
|
||||
else Result := ExecuteCommand('-break-insert *%u', [AAddress], R);
|
||||
end;
|
||||
end;
|
||||
|
||||
ResultList := TGDBMINameValueList.Create(R, ['bkpt']);
|
||||
ABreakID := StrToIntDef(ResultList.Values['number'], 0);
|
||||
@ -6695,7 +6720,7 @@ begin
|
||||
if FReplaceId <> 0
|
||||
then ExecBreakDelete(FReplaceId);
|
||||
|
||||
FValid := ExecBreakInsert(FSource, FLine, FEnabled, FBreakID, FHitCnt, FAddr);
|
||||
FValid := ExecBreakInsert(FKind, FAddress, FSource, FLine, FEnabled, FBreakID, FHitCnt, FAddress);
|
||||
if not FValid then Exit;
|
||||
|
||||
if (FExpression <> '') and not (dcsCanceled in SeenStates)
|
||||
@ -6709,7 +6734,7 @@ begin
|
||||
ExecBreakDelete(FBreakID);
|
||||
FBreakID := 0;
|
||||
FValid := False;
|
||||
FAddr := 0;
|
||||
FAddress := 0;
|
||||
FHitCnt := 0;
|
||||
end;
|
||||
end;
|
||||
@ -6718,6 +6743,7 @@ constructor TGDBMIDebuggerCommandBreakInsert.Create(AOwner: TGDBMIDebugger; ASou
|
||||
ALine: Integer; AEnabled: Boolean; AnExpression: string; AReplaceId: Integer);
|
||||
begin
|
||||
inherited Create(AOwner);
|
||||
FKind := bpkSource;
|
||||
FSource := ASource;
|
||||
FLine := ALine;
|
||||
FEnabled := AEnabled;
|
||||
@ -6725,6 +6751,18 @@ begin
|
||||
FReplaceId := AReplaceId;
|
||||
end;
|
||||
|
||||
constructor TGDBMIDebuggerCommandBreakInsert.Create(AOwner: TGDBMIDebugger;
|
||||
AAddress: TDBGPtr; AEnabled: Boolean; AnExpression: string;
|
||||
AReplaceId: Integer);
|
||||
begin
|
||||
inherited Create(AOwner);
|
||||
FKind := bpkAddress;
|
||||
FAddress := AAddress;
|
||||
FEnabled := AEnabled;
|
||||
FExpression := AnExpression;
|
||||
FReplaceId := AReplaceId;
|
||||
end;
|
||||
|
||||
function TGDBMIDebuggerCommandBreakInsert.DebugText: String;
|
||||
begin
|
||||
Result := Format('%s: Source=%s, Line=%d, Enabled=%s', [ClassName, FSource, FLine, dbgs(FEnabled)]);
|
||||
@ -6873,6 +6911,15 @@ begin
|
||||
EndUpdate;
|
||||
end;
|
||||
|
||||
procedure TGDBMIBreakPoint.SetAddress(const AValue: TDBGPtr);
|
||||
begin
|
||||
if (Address = AValue) then exit;
|
||||
inherited;
|
||||
if (Debugger = nil) then Exit;
|
||||
if TGDBMIDebugger(Debugger).State in [dsPause, dsRun]
|
||||
then SetBreakpoint;
|
||||
end;
|
||||
|
||||
procedure TGDBMIBreakPoint.SetBreakpoint;
|
||||
begin
|
||||
if Debugger = nil then Exit;
|
||||
@ -6894,8 +6941,18 @@ begin
|
||||
if (FCurrentCmd is TGDBMIDebuggerCommandBreakInsert) and (FCurrentCmd.State = dcsQueued)
|
||||
then begin
|
||||
// update the current object
|
||||
TGDBMIDebuggerCommandBreakInsert(FCurrentCmd).Source := Source;
|
||||
TGDBMIDebuggerCommandBreakInsert(FCurrentCmd).Line := Line;
|
||||
TGDBMIDebuggerCommandBreakInsert(FCurrentCmd).Kind := Kind;
|
||||
case Kind of
|
||||
bpkSource:
|
||||
begin
|
||||
TGDBMIDebuggerCommandBreakInsert(FCurrentCmd).Source := Source;
|
||||
TGDBMIDebuggerCommandBreakInsert(FCurrentCmd).Line := Line;
|
||||
end;
|
||||
bpkAddress:
|
||||
begin
|
||||
TGDBMIDebuggerCommandBreakInsert(FCurrentCmd).Address := Address;
|
||||
end;
|
||||
end;
|
||||
TGDBMIDebuggerCommandBreakInsert(FCurrentCmd).Enabled := Enabled;
|
||||
TGDBMIDebuggerCommandBreakInsert(FCurrentCmd).Expression := FParsedExpression;
|
||||
exit;
|
||||
@ -6918,8 +6975,12 @@ begin
|
||||
end;
|
||||
|
||||
FUpdateFlags := [];
|
||||
FCurrentCmd:= TGDBMIDebuggerCommandBreakInsert.Create(TGDBMIDebugger(Debugger),
|
||||
Source, Line , Enabled, FParsedExpression, FBreakID);
|
||||
case Kind of
|
||||
bpkSource:
|
||||
FCurrentCmd := TGDBMIDebuggerCommandBreakInsert.Create(TGDBMIDebugger(Debugger), Source, Line, Enabled, FParsedExpression, FBreakID);
|
||||
bpkAddress:
|
||||
FCurrentCmd := TGDBMIDebuggerCommandBreakInsert.Create(TGDBMIDebugger(Debugger), Address, Enabled, FParsedExpression, FBreakID);
|
||||
end;
|
||||
FBreakID := 0; // will be replaced => no longer valid
|
||||
FCurrentCmd.OnDestroy := @DoCommandDestroyed;
|
||||
FCurrentCmd.OnExecuted := @DoCommandExecuted;
|
||||
@ -6959,7 +7020,7 @@ begin
|
||||
and (TGDBMIDebugger(Debugger).FBreakAtMain = nil)
|
||||
then begin
|
||||
// Check if this BP is at the same location as the temp break
|
||||
if TGDBMIDebuggerCommandBreakInsert(Sender).Addr = TGDBMIDebugger(Debugger).FMainAddr
|
||||
if TGDBMIDebuggerCommandBreakInsert(Sender).Address = TGDBMIDebugger(Debugger).FMainAddr
|
||||
then TGDBMIDebugger(Debugger).FBreakAtMain := Self;
|
||||
end;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user