debugger: implement address breakpoints

git-svn-id: trunk@30673 -
This commit is contained in:
paul 2011-05-11 02:51:08 +00:00
parent 271b185f2c
commit f805a11b16
5 changed files with 233 additions and 89 deletions

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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;