mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-07 07:16:30 +02:00
* Added breakpont properties dialog. Modified patch by Benito van der Zander (issue #12882)
git-svn-id: trunk@18115 -
This commit is contained in:
parent
8d632ac72b
commit
c569ccca33
3
.gitattributes
vendored
3
.gitattributes
vendored
@ -1601,6 +1601,9 @@ debugger/assemblerdlg.pp svneol=native#text/pascal
|
||||
debugger/breakpointsdlg.lfm svneol=native#text/plain
|
||||
debugger/breakpointsdlg.lrs svneol=native#text/pascal
|
||||
debugger/breakpointsdlg.pp svneol=native#text/pascal
|
||||
debugger/breakpropertydlg.lfm svneol=native#text/pascal
|
||||
debugger/breakpropertydlg.lrs svneol=native#text/pascal
|
||||
debugger/breakpropertydlg.pas svneol=native#text/pascal
|
||||
debugger/callstackdlg.lfm svneol=native#text/plain
|
||||
debugger/callstackdlg.lrs svneol=native#text/pascal
|
||||
debugger/callstackdlg.pp svneol=native#text/pascal
|
||||
|
@ -123,7 +123,7 @@ function GetBreakPointActionsDescription(ABreakpoint: TBaseBreakpoint): string;
|
||||
|
||||
implementation
|
||||
uses
|
||||
LazarusIDEStrConsts;
|
||||
LazarusIDEStrConsts, BaseDebugManager;
|
||||
function GetBreakPointStateDescription(ABreakpoint: TBaseBreakpoint): string;
|
||||
const
|
||||
// enabled valid
|
||||
@ -634,8 +634,16 @@ begin
|
||||
end;
|
||||
|
||||
procedure TBreakPointsDlg.ShowProperties;
|
||||
var
|
||||
Item: TListItem;
|
||||
CurBreakPoint: TIDEBreakPoint;
|
||||
begin
|
||||
ShowMessage(lisNotImplementedYet2);
|
||||
Item:=lvBreakPoints.Selected;
|
||||
if Item = nil then exit;
|
||||
|
||||
CurBreakPoint:=TIDEBreakPoint(Item.Data);
|
||||
|
||||
DebugBoss.ShowBreakPointProperties(CurBreakPoint);
|
||||
end;
|
||||
|
||||
|
||||
|
310
debugger/breakpropertydlg.lfm
Normal file
310
debugger/breakpropertydlg.lfm
Normal file
@ -0,0 +1,310 @@
|
||||
inherited BreakPropertyDlg: TBreakPropertyDlg
|
||||
Left = 329
|
||||
Height = 367
|
||||
Top = 288
|
||||
Width = 387
|
||||
HorzScrollBar.Page = 382
|
||||
HorzScrollBar.Range = 392
|
||||
HorzScrollBar.Visible = True
|
||||
VertScrollBar.Page = 188
|
||||
VertScrollBar.Range = 209
|
||||
VertScrollBar.Visible = True
|
||||
AutoScroll = False
|
||||
Caption = 'Breakpoint Properties'
|
||||
ClientHeight = 367
|
||||
ClientWidth = 387
|
||||
object lblFileName: TLabel[0]
|
||||
AnchorSideTop.Side = asrCenter
|
||||
Left = 8
|
||||
Height = 13
|
||||
Top = 14
|
||||
Width = 55
|
||||
Caption = 'Filename:'
|
||||
ParentColor = False
|
||||
end
|
||||
object lblLine: TLabel[1]
|
||||
AnchorSideLeft.Control = lblFileName
|
||||
AnchorSideTop.Side = asrCenter
|
||||
Left = 8
|
||||
Height = 13
|
||||
Top = 41
|
||||
Width = 28
|
||||
Caption = 'Line:'
|
||||
ParentColor = False
|
||||
end
|
||||
object lblCondition: TLabel[2]
|
||||
AnchorSideLeft.Control = lblFileName
|
||||
AnchorSideTop.Side = asrCenter
|
||||
Left = 8
|
||||
Height = 13
|
||||
Top = 68
|
||||
Width = 57
|
||||
Caption = 'Condition:'
|
||||
ParentColor = False
|
||||
end
|
||||
object lblHitCount: TLabel[3]
|
||||
AnchorSideLeft.Control = lblFileName
|
||||
AnchorSideTop.Side = asrCenter
|
||||
Left = 8
|
||||
Height = 13
|
||||
Top = 95
|
||||
Width = 61
|
||||
Caption = 'Hitcounter:'
|
||||
ParentColor = False
|
||||
end
|
||||
object lblGroup: TLabel[4]
|
||||
AnchorSideLeft.Control = lblFileName
|
||||
AnchorSideTop.Side = asrCenter
|
||||
Left = 8
|
||||
Height = 13
|
||||
Top = 152
|
||||
Width = 38
|
||||
Caption = 'Group:'
|
||||
ParentColor = False
|
||||
end
|
||||
object lblAutoContinue: TLabel[5]
|
||||
Left = 9
|
||||
Height = 13
|
||||
Top = 124
|
||||
Width = 106
|
||||
Caption = 'Auto continue (ms)'
|
||||
ParentColor = False
|
||||
end
|
||||
object edtAutocontinueMS: TEdit[6]
|
||||
AnchorSideRight.Control = Owner
|
||||
AnchorSideRight.Side = asrBottom
|
||||
Left = 137
|
||||
Height = 23
|
||||
Top = 117
|
||||
Width = 251
|
||||
Anchors = [akTop, akLeft, akRight]
|
||||
BorderSpacing.Around = 4
|
||||
TabOrder = 0
|
||||
Text = 'edtAutocontinueMS'
|
||||
end
|
||||
object edtCounter: TEdit[7]
|
||||
AnchorSideTop.Side = asrBottom
|
||||
AnchorSideRight.Control = Owner
|
||||
AnchorSideRight.Side = asrBottom
|
||||
Left = 137
|
||||
Height = 23
|
||||
Top = 90
|
||||
Width = 251
|
||||
Anchors = [akTop, akLeft, akRight]
|
||||
BorderSpacing.Top = 4
|
||||
BorderSpacing.Around = 4
|
||||
TabOrder = 1
|
||||
Text = 'edtCounter'
|
||||
end
|
||||
object edtCondition: TEdit[8]
|
||||
AnchorSideTop.Side = asrBottom
|
||||
AnchorSideRight.Control = Owner
|
||||
AnchorSideRight.Side = asrBottom
|
||||
Left = 137
|
||||
Height = 23
|
||||
Top = 63
|
||||
Width = 251
|
||||
Anchors = [akTop, akLeft, akRight]
|
||||
BorderSpacing.Top = 4
|
||||
BorderSpacing.Around = 4
|
||||
TabOrder = 2
|
||||
Text = 'edtCondition'
|
||||
end
|
||||
object edtLine: TEdit[9]
|
||||
AnchorSideTop.Side = asrBottom
|
||||
AnchorSideRight.Control = Owner
|
||||
AnchorSideRight.Side = asrBottom
|
||||
Left = 137
|
||||
Height = 23
|
||||
Top = 36
|
||||
Width = 251
|
||||
Anchors = [akTop, akLeft, akRight]
|
||||
BorderSpacing.Top = 4
|
||||
BorderSpacing.Around = 4
|
||||
Color = clBtnFace
|
||||
ReadOnly = True
|
||||
TabOrder = 3
|
||||
Text = 'edtLine'
|
||||
end
|
||||
object edtFilename: TEdit[10]
|
||||
AnchorSideTop.Side = asrCenter
|
||||
AnchorSideRight.Control = Owner
|
||||
AnchorSideRight.Side = asrBottom
|
||||
Left = 137
|
||||
Height = 24
|
||||
Top = 8
|
||||
Width = 247
|
||||
Anchors = [akTop, akLeft, akRight]
|
||||
BorderSpacing.Right = 4
|
||||
BorderSpacing.Around = 4
|
||||
Color = clBtnFace
|
||||
ReadOnly = True
|
||||
TabOrder = 4
|
||||
Text = 'edtFilename'
|
||||
end
|
||||
object cmbGroup: TComboBox[11]
|
||||
AnchorSideRight.Control = Owner
|
||||
AnchorSideRight.Side = asrBottom
|
||||
Left = 137
|
||||
Height = 25
|
||||
Top = 144
|
||||
Width = 251
|
||||
Anchors = [akTop, akLeft, akRight]
|
||||
BorderSpacing.Around = 4
|
||||
TabOrder = 5
|
||||
Text = 'cmbGroup'
|
||||
end
|
||||
object gbActions: TGroupBox[12]
|
||||
AnchorSideLeft.Control = Owner
|
||||
AnchorSideRight.Control = Owner
|
||||
AnchorSideRight.Side = asrBottom
|
||||
Left = 4
|
||||
Height = 149
|
||||
Top = 176
|
||||
Width = 384
|
||||
Anchors = [akTop, akLeft, akRight]
|
||||
BorderSpacing.Around = 4
|
||||
Caption = 'Actions'
|
||||
ClientHeight = 132
|
||||
ClientWidth = 380
|
||||
TabOrder = 6
|
||||
object chkActionBreak: TCheckBox
|
||||
Left = 6
|
||||
Height = 20
|
||||
Top = 5
|
||||
Width = 56
|
||||
Caption = 'Break'
|
||||
TabOrder = 0
|
||||
end
|
||||
object chkEnableGroups: TCheckBox
|
||||
Left = 6
|
||||
Height = 20
|
||||
Top = 29
|
||||
Width = 101
|
||||
Caption = 'Enable goups'
|
||||
TabOrder = 1
|
||||
end
|
||||
object chkDisableGroups: TCheckBox
|
||||
Left = 6
|
||||
Height = 20
|
||||
Top = 53
|
||||
Width = 108
|
||||
Caption = 'Disable groups'
|
||||
TabOrder = 2
|
||||
end
|
||||
object edtEnableGroups: TEditButton
|
||||
Left = 130
|
||||
Height = 23
|
||||
Top = 29
|
||||
Width = 221
|
||||
Anchors = [akTop, akLeft, akRight]
|
||||
ButtonWidth = 23
|
||||
Enabled = False
|
||||
NumGlyphs = 1
|
||||
OnButtonClick = edtEnableGroupsButtonClick
|
||||
TabOrder = 3
|
||||
end
|
||||
object edtDisableGroups: TEditButton
|
||||
Left = 130
|
||||
Height = 23
|
||||
Top = 53
|
||||
Width = 221
|
||||
Anchors = [akTop, akLeft, akRight]
|
||||
ButtonWidth = 23
|
||||
Enabled = False
|
||||
NumGlyphs = 1
|
||||
OnButtonClick = edtDisableGroupsButtonClick
|
||||
TabOrder = 4
|
||||
end
|
||||
object chkEvalExpression: TCheckBox
|
||||
Left = 6
|
||||
Height = 20
|
||||
Top = 77
|
||||
Width = 113
|
||||
Caption = 'Eval expression'
|
||||
Enabled = False
|
||||
TabOrder = 5
|
||||
end
|
||||
object chkLogMessage: TCheckBox
|
||||
Left = 6
|
||||
Height = 20
|
||||
Top = 101
|
||||
Width = 98
|
||||
Caption = 'Log message'
|
||||
Enabled = False
|
||||
TabOrder = 6
|
||||
end
|
||||
object edtEvalExpression: TEdit
|
||||
Left = 130
|
||||
Height = 23
|
||||
Top = 77
|
||||
Width = 244
|
||||
Anchors = [akTop, akLeft, akRight]
|
||||
Enabled = False
|
||||
TabOrder = 7
|
||||
Text = 'edtEvalExpression'
|
||||
end
|
||||
object edtLogMessage: TEdit
|
||||
Left = 130
|
||||
Height = 23
|
||||
Top = 101
|
||||
Width = 244
|
||||
Anchors = [akTop, akLeft, akRight]
|
||||
Enabled = False
|
||||
TabOrder = 8
|
||||
Text = 'Edit1'
|
||||
end
|
||||
end
|
||||
object btnHelp: TBitBtn[13]
|
||||
AnchorSideLeft.Control = Owner
|
||||
AnchorSideBottom.Control = Owner
|
||||
AnchorSideBottom.Side = asrBottom
|
||||
Left = 6
|
||||
Height = 26
|
||||
Top = 335
|
||||
Width = 35
|
||||
Anchors = [akLeft, akBottom]
|
||||
AutoSize = True
|
||||
BorderSpacing.Around = 6
|
||||
Caption = 'Help'
|
||||
NumGlyphs = 0
|
||||
OnClick = btnHelpClick
|
||||
TabOrder = 7
|
||||
end
|
||||
object btnOK: TBitBtn[14]
|
||||
AnchorSideRight.Control = btnCancel
|
||||
AnchorSideBottom.Control = Owner
|
||||
AnchorSideBottom.Side = asrBottom
|
||||
Left = 304
|
||||
Height = 26
|
||||
Top = 335
|
||||
Width = 27
|
||||
Anchors = [akRight, akBottom]
|
||||
AutoSize = True
|
||||
BorderSpacing.Around = 6
|
||||
Caption = 'OK'
|
||||
Default = True
|
||||
ModalResult = 1
|
||||
NumGlyphs = 0
|
||||
OnClick = btnOKClick
|
||||
TabOrder = 8
|
||||
end
|
||||
object btnCancel: TBitBtn[15]
|
||||
AnchorSideRight.Control = Owner
|
||||
AnchorSideRight.Side = asrBottom
|
||||
AnchorSideBottom.Control = Owner
|
||||
AnchorSideBottom.Side = asrBottom
|
||||
Left = 337
|
||||
Height = 26
|
||||
Top = 335
|
||||
Width = 49
|
||||
Anchors = [akRight, akBottom]
|
||||
AutoSize = True
|
||||
BorderSpacing.Around = 6
|
||||
Cancel = True
|
||||
Caption = 'Cancel'
|
||||
ModalResult = 2
|
||||
NumGlyphs = 0
|
||||
TabOrder = 9
|
||||
end
|
||||
end
|
96
debugger/breakpropertydlg.lrs
Normal file
96
debugger/breakpropertydlg.lrs
Normal file
@ -0,0 +1,96 @@
|
||||
{ This is an automatically generated lazarus resource file }
|
||||
|
||||
LazarusResources.Add('TBreakPropertyDlg','FORMDATA',[
|
||||
'TPF0'#241#17'TBreakPropertyDlg'#16'BreakPropertyDlg'#4'Left'#3'I'#1#6'Height'
|
||||
+#3'o'#1#3'Top'#3' '#1#5'Width'#3#131#1#18'HorzScrollBar.Page'#3'~'#1#19'Horz'
|
||||
+'ScrollBar.Range'#3#136#1#21'HorzScrollBar.Visible'#9#18'VertScrollBar.Page'
|
||||
+#3#188#0#19'VertScrollBar.Range'#3#209#0#21'VertScrollBar.Visible'#9#10'Auto'
|
||||
+'Scroll'#8#7'Caption'#6#21'Breakpoint Properties'#12'ClientHeight'#3'o'#1#11
|
||||
+'ClientWidth'#3#131#1#0#242#2#0#6'TLabel'#11'lblFileName'#18'AnchorSideTop.S'
|
||||
+'ide'#7#9'asrCenter'#4'Left'#2#8#6'Height'#2#13#3'Top'#2#14#5'Width'#2'7'#7
|
||||
+'Caption'#6#9'Filename:'#11'ParentColor'#8#0#0#242#2#1#6'TLabel'#7'lblLine'
|
||||
+#22'AnchorSideLeft.Control'#7#11'lblFileName'#18'AnchorSideTop.Side'#7#9'asr'
|
||||
+'Center'#4'Left'#2#8#6'Height'#2#13#3'Top'#2')'#5'Width'#2#28#7'Caption'#6#5
|
||||
+'Line:'#11'ParentColor'#8#0#0#242#2#2#6'TLabel'#12'lblCondition'#22'AnchorSi'
|
||||
+'deLeft.Control'#7#11'lblFileName'#18'AnchorSideTop.Side'#7#9'asrCenter'#4'L'
|
||||
+'eft'#2#8#6'Height'#2#13#3'Top'#2'D'#5'Width'#2'9'#7'Caption'#6#10'Condition'
|
||||
+':'#11'ParentColor'#8#0#0#242#2#3#6'TLabel'#11'lblHitCount'#22'AnchorSideLef'
|
||||
+'t.Control'#7#11'lblFileName'#18'AnchorSideTop.Side'#7#9'asrCenter'#4'Left'#2
|
||||
+#8#6'Height'#2#13#3'Top'#2'_'#5'Width'#2'='#7'Caption'#6#11'Hitcounter:'#11
|
||||
+'ParentColor'#8#0#0#242#2#4#6'TLabel'#8'lblGroup'#22'AnchorSideLeft.Control'
|
||||
+#7#11'lblFileName'#18'AnchorSideTop.Side'#7#9'asrCenter'#4'Left'#2#8#6'Heigh'
|
||||
+'t'#2#13#3'Top'#3#152#0#5'Width'#2'&'#7'Caption'#6#6'Group:'#11'ParentColor'
|
||||
+#8#0#0#242#2#5#6'TLabel'#15'lblAutoContinue'#4'Left'#2#9#6'Height'#2#13#3'To'
|
||||
+'p'#2'|'#5'Width'#2'j'#7'Caption'#6#18'Auto continue (ms)'#11'ParentColor'#8
|
||||
+#0#0#242#2#6#5'TEdit'#17'edtAutocontinueMS'#23'AnchorSideRight.Control'#7#5
|
||||
+'Owner'#20'AnchorSideRight.Side'#7#9'asrBottom'#4'Left'#3#137#0#6'Height'#2
|
||||
+#23#3'Top'#2'u'#5'Width'#3#251#0#7'Anchors'#11#5'akTop'#6'akLeft'#7'akRight'
|
||||
+#0#20'BorderSpacing.Around'#2#4#8'TabOrder'#2#0#4'Text'#6#17'edtAutocontinue'
|
||||
+'MS'#0#0#242#2#7#5'TEdit'#10'edtCounter'#18'AnchorSideTop.Side'#7#9'asrBotto'
|
||||
+'m'#23'AnchorSideRight.Control'#7#5'Owner'#20'AnchorSideRight.Side'#7#9'asrB'
|
||||
+'ottom'#4'Left'#3#137#0#6'Height'#2#23#3'Top'#2'Z'#5'Width'#3#251#0#7'Anchor'
|
||||
+'s'#11#5'akTop'#6'akLeft'#7'akRight'#0#17'BorderSpacing.Top'#2#4#20'BorderSp'
|
||||
+'acing.Around'#2#4#8'TabOrder'#2#1#4'Text'#6#10'edtCounter'#0#0#242#2#8#5'TE'
|
||||
+'dit'#12'edtCondition'#18'AnchorSideTop.Side'#7#9'asrBottom'#23'AnchorSideRi'
|
||||
+'ght.Control'#7#5'Owner'#20'AnchorSideRight.Side'#7#9'asrBottom'#4'Left'#3
|
||||
+#137#0#6'Height'#2#23#3'Top'#2'?'#5'Width'#3#251#0#7'Anchors'#11#5'akTop'#6
|
||||
+'akLeft'#7'akRight'#0#17'BorderSpacing.Top'#2#4#20'BorderSpacing.Around'#2#4
|
||||
+#8'TabOrder'#2#2#4'Text'#6#12'edtCondition'#0#0#242#2#9#5'TEdit'#7'edtLine'
|
||||
+#18'AnchorSideTop.Side'#7#9'asrBottom'#23'AnchorSideRight.Control'#7#5'Owner'
|
||||
+#20'AnchorSideRight.Side'#7#9'asrBottom'#4'Left'#3#137#0#6'Height'#2#23#3'To'
|
||||
+'p'#2'$'#5'Width'#3#251#0#7'Anchors'#11#5'akTop'#6'akLeft'#7'akRight'#0#17'B'
|
||||
+'orderSpacing.Top'#2#4#20'BorderSpacing.Around'#2#4#5'Color'#7#9'clBtnFace'#8
|
||||
+'ReadOnly'#9#8'TabOrder'#2#3#4'Text'#6#7'edtLine'#0#0#242#2#10#5'TEdit'#11'e'
|
||||
+'dtFilename'#18'AnchorSideTop.Side'#7#9'asrCenter'#23'AnchorSideRight.Contro'
|
||||
+'l'#7#5'Owner'#20'AnchorSideRight.Side'#7#9'asrBottom'#4'Left'#3#137#0#6'Hei'
|
||||
+'ght'#2#24#3'Top'#2#8#5'Width'#3#247#0#7'Anchors'#11#5'akTop'#6'akLeft'#7'ak'
|
||||
+'Right'#0#19'BorderSpacing.Right'#2#4#20'BorderSpacing.Around'#2#4#5'Color'#7
|
||||
+#9'clBtnFace'#8'ReadOnly'#9#8'TabOrder'#2#4#4'Text'#6#11'edtFilename'#0#0#242
|
||||
+#2#11#9'TComboBox'#8'cmbGroup'#23'AnchorSideRight.Control'#7#5'Owner'#20'Anc'
|
||||
+'horSideRight.Side'#7#9'asrBottom'#4'Left'#3#137#0#6'Height'#2#25#3'Top'#3
|
||||
+#144#0#5'Width'#3#251#0#7'Anchors'#11#5'akTop'#6'akLeft'#7'akRight'#0#20'Bor'
|
||||
+'derSpacing.Around'#2#4#8'TabOrder'#2#5#4'Text'#6#8'cmbGroup'#0#0#242#2#12#9
|
||||
+'TGroupBox'#9'gbActions'#22'AnchorSideLeft.Control'#7#5'Owner'#23'AnchorSide'
|
||||
+'Right.Control'#7#5'Owner'#20'AnchorSideRight.Side'#7#9'asrBottom'#4'Left'#2
|
||||
+#4#6'Height'#3#149#0#3'Top'#3#176#0#5'Width'#3#128#1#7'Anchors'#11#5'akTop'#6
|
||||
+'akLeft'#7'akRight'#0#20'BorderSpacing.Around'#2#4#7'Caption'#6#7'Actions'#12
|
||||
+'ClientHeight'#3#132#0#11'ClientWidth'#3'|'#1#8'TabOrder'#2#6#0#9'TCheckBox'
|
||||
+#14'chkActionBreak'#4'Left'#2#6#6'Height'#2#20#3'Top'#2#5#5'Width'#2'8'#7'Ca'
|
||||
+'ption'#6#5'Break'#8'TabOrder'#2#0#0#0#9'TCheckBox'#15'chkEnableGroups'#4'Le'
|
||||
+'ft'#2#6#6'Height'#2#20#3'Top'#2#29#5'Width'#2'e'#7'Caption'#6#12'Enable gou'
|
||||
+'ps'#8'TabOrder'#2#1#0#0#9'TCheckBox'#16'chkDisableGroups'#4'Left'#2#6#6'Hei'
|
||||
+'ght'#2#20#3'Top'#2'5'#5'Width'#2'l'#7'Caption'#6#14'Disable groups'#8'TabOr'
|
||||
+'der'#2#2#0#0#11'TEditButton'#15'edtEnableGroups'#4'Left'#3#130#0#6'Height'#2
|
||||
+#23#3'Top'#2#29#5'Width'#3#221#0#7'Anchors'#11#5'akTop'#6'akLeft'#7'akRight'
|
||||
+#0#11'ButtonWidth'#2#23#7'Enabled'#8#9'NumGlyphs'#2#1#13'OnButtonClick'#7#26
|
||||
+'edtEnableGroupsButtonClick'#8'TabOrder'#2#3#0#0#11'TEditButton'#16'edtDisab'
|
||||
+'leGroups'#4'Left'#3#130#0#6'Height'#2#23#3'Top'#2'5'#5'Width'#3#221#0#7'Anc'
|
||||
,'hors'#11#5'akTop'#6'akLeft'#7'akRight'#0#11'ButtonWidth'#2#23#7'Enabled'#8#9
|
||||
+'NumGlyphs'#2#1#13'OnButtonClick'#7#27'edtDisableGroupsButtonClick'#8'TabOrd'
|
||||
+'er'#2#4#0#0#9'TCheckBox'#17'chkEvalExpression'#4'Left'#2#6#6'Height'#2#20#3
|
||||
+'Top'#2'M'#5'Width'#2'q'#7'Caption'#6#15'Eval expression'#7'Enabled'#8#8'Tab'
|
||||
+'Order'#2#5#0#0#9'TCheckBox'#13'chkLogMessage'#4'Left'#2#6#6'Height'#2#20#3
|
||||
+'Top'#2'e'#5'Width'#2'b'#7'Caption'#6#11'Log message'#7'Enabled'#8#8'TabOrde'
|
||||
+'r'#2#6#0#0#5'TEdit'#17'edtEvalExpression'#4'Left'#3#130#0#6'Height'#2#23#3
|
||||
+'Top'#2'M'#5'Width'#3#244#0#7'Anchors'#11#5'akTop'#6'akLeft'#7'akRight'#0#7
|
||||
+'Enabled'#8#8'TabOrder'#2#7#4'Text'#6#17'edtEvalExpression'#0#0#5'TEdit'#13
|
||||
+'edtLogMessage'#4'Left'#3#130#0#6'Height'#2#23#3'Top'#2'e'#5'Width'#3#244#0#7
|
||||
+'Anchors'#11#5'akTop'#6'akLeft'#7'akRight'#0#7'Enabled'#8#8'TabOrder'#2#8#4
|
||||
+'Text'#6#5'Edit1'#0#0#0#242#2#13#7'TBitBtn'#7'btnHelp'#22'AnchorSideLeft.Con'
|
||||
+'trol'#7#5'Owner'#24'AnchorSideBottom.Control'#7#5'Owner'#21'AnchorSideBotto'
|
||||
+'m.Side'#7#9'asrBottom'#4'Left'#2#6#6'Height'#2#26#3'Top'#3'O'#1#5'Width'#2
|
||||
+'#'#7'Anchors'#11#6'akLeft'#8'akBottom'#0#8'AutoSize'#9#20'BorderSpacing.Aro'
|
||||
+'und'#2#6#7'Caption'#6#4'Help'#9'NumGlyphs'#2#0#7'OnClick'#7#12'btnHelpClick'
|
||||
+#8'TabOrder'#2#7#0#0#242#2#14#7'TBitBtn'#5'btnOK'#23'AnchorSideRight.Control'
|
||||
+#7#9'btnCancel'#24'AnchorSideBottom.Control'#7#5'Owner'#21'AnchorSideBottom.'
|
||||
+'Side'#7#9'asrBottom'#4'Left'#3'0'#1#6'Height'#2#26#3'Top'#3'O'#1#5'Width'#2
|
||||
+#27#7'Anchors'#11#7'akRight'#8'akBottom'#0#8'AutoSize'#9#20'BorderSpacing.Ar'
|
||||
+'ound'#2#6#7'Caption'#6#2'OK'#7'Default'#9#11'ModalResult'#2#1#9'NumGlyphs'#2
|
||||
+#0#7'OnClick'#7#10'btnOKClick'#8'TabOrder'#2#8#0#0#242#2#15#7'TBitBtn'#9'btn'
|
||||
+'Cancel'#23'AnchorSideRight.Control'#7#5'Owner'#20'AnchorSideRight.Side'#7#9
|
||||
+'asrBottom'#24'AnchorSideBottom.Control'#7#5'Owner'#21'AnchorSideBottom.Side'
|
||||
+#7#9'asrBottom'#4'Left'#3'Q'#1#6'Height'#2#26#3'Top'#3'O'#1#5'Width'#2'1'#7
|
||||
+'Anchors'#11#7'akRight'#8'akBottom'#0#8'AutoSize'#9#20'BorderSpacing.Around'
|
||||
+#2#6#6'Cancel'#9#7'Caption'#6#6'Cancel'#11'ModalResult'#2#2#9'NumGlyphs'#2#0
|
||||
+#8'TabOrder'#2#9#0#0#0
|
||||
]);
|
188
debugger/breakpropertydlg.pas
Normal file
188
debugger/breakpropertydlg.pas
Normal file
@ -0,0 +1,188 @@
|
||||
unit BreakPropertyDlg;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
|
||||
ExtCtrls, StdCtrls, Buttons, DebuggerDlg, Debugger, ButtonPanel, EditBtn,
|
||||
BaseDebugManager, IDEContextHelpEdit;
|
||||
|
||||
type
|
||||
|
||||
{ TBreakPropertyDlg }
|
||||
|
||||
TBreakPropertyDlg = class(TDebuggerDlg)
|
||||
btnCancel: TBitBtn;
|
||||
btnHelp: TBitBtn;
|
||||
btnOK: TBitBtn;
|
||||
chkEnableGroups: TCheckBox;
|
||||
chkDisableGroups: TCheckBox;
|
||||
chkEvalExpression: TCheckBox;
|
||||
chkLogMessage: TCheckBox;
|
||||
chkActionBreak: TCheckBox;
|
||||
cmbGroup: TComboBox;
|
||||
edtEvalExpression: TEdit;
|
||||
edtLogMessage: TEdit;
|
||||
edtEnableGroups: TEditButton;
|
||||
edtDisableGroups: TEditButton;
|
||||
edtAutocontinueMS: TEdit;
|
||||
edtCondition: TEdit;
|
||||
edtCounter: TEdit;
|
||||
edtFilename: TEdit;
|
||||
edtLine: TEdit;
|
||||
gbActions: TGroupBox;
|
||||
lblFileName: TLabel;
|
||||
lblLine: TLabel;
|
||||
lblCondition: TLabel;
|
||||
lblHitCount: TLabel;
|
||||
lblGroup: TLabel;
|
||||
lblAutoContinue: TLabel;
|
||||
procedure btnHelpClick(Sender: TObject);
|
||||
procedure btnOKClick(Sender: TObject);
|
||||
procedure BreakPointRemove(const ASender: TIDEBreakPoints;
|
||||
const ABreakpoint: TIDEBreakPoint);
|
||||
procedure BreakPointUpdate(const ASender: TIDEBreakPoints;
|
||||
const ABreakpoint: TIDEBreakPoint);
|
||||
procedure edtDisableGroupsButtonClick(Sender: TObject);
|
||||
procedure edtEnableGroupsButtonClick(Sender: TObject);
|
||||
private
|
||||
{ private declarations }
|
||||
FBreakpointsNotification : TIDEBreakPointsNotification;
|
||||
FBreakpoint: TIDEBreakPoint;
|
||||
protected
|
||||
procedure DoEndUpdate; override;
|
||||
procedure UpdateInfo;
|
||||
public
|
||||
{ public declarations }
|
||||
constructor Create(AOwner: TComponent; ABreakPoint: TIDEBreakPoint);overload;
|
||||
destructor Destroy; override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TBreakPropertyDlg }
|
||||
|
||||
procedure TBreakPropertyDlg.BreakPointUpdate(
|
||||
const ASender: TIDEBreakPoints; const ABreakpoint: TIDEBreakPoint);
|
||||
begin
|
||||
UpdateInfo;
|
||||
end;
|
||||
|
||||
procedure TBreakPropertyDlg.btnHelpClick(Sender: TObject);
|
||||
begin
|
||||
ShowContextHelpForIDE(btnHelp);
|
||||
end;
|
||||
|
||||
procedure TBreakPropertyDlg.BreakPointRemove(
|
||||
const ASender: TIDEBreakPoints; const ABreakpoint: TIDEBreakPoint);
|
||||
begin
|
||||
if ABreakpoint = FBreakpoint
|
||||
then ModalResult := mrCancel;
|
||||
end;
|
||||
|
||||
procedure TBreakPropertyDlg.btnOKClick(Sender: TObject);
|
||||
var
|
||||
Actions: TIDEBreakPointActions;
|
||||
begin
|
||||
if FBreakpoint = nil then Exit;
|
||||
|
||||
FBreakpointsNotification.OnUpdate := nil;
|
||||
// filename
|
||||
// line
|
||||
FBreakpoint.SetLocation(edtFilename.Text, StrToIntDef(edtLine.Text, 1));
|
||||
// expression
|
||||
FBreakpoint.Expression := edtCondition.Text;
|
||||
// hitcount
|
||||
FBreakpoint.BreakHitCount := StrToIntDef(edtCounter.Text, FBreakpoint.HitCount);
|
||||
//auto continue
|
||||
FBreakpoint.AutoContinueTime := StrToIntDef(edtAutocontinueMS.Text, FBreakpoint.AutoContinueTime);
|
||||
// group
|
||||
FBreakpoint.Group := DebugBoss.BreakPointGroups.GetGroupByName(cmbGroup.Text);
|
||||
// actions
|
||||
Actions := [];
|
||||
if chkActionBreak.Checked then Include(Actions, bpaStop);
|
||||
if chkDisableGroups.Checked then Include(Actions, bpaDisableGroup);
|
||||
if chkEnableGroups.Checked then Include(Actions, bpaEnableGroup);
|
||||
// if chkEvalExpression.Checked then Include(Actions, bpaEValExpression);
|
||||
// if chkLogMessage.Checked then Include(Actions, bpaLogMessage);
|
||||
FBreakpoint.Actions := Actions;
|
||||
end;
|
||||
|
||||
procedure TBreakPropertyDlg.DoEndUpdate;
|
||||
begin
|
||||
inherited DoEndUpdate;
|
||||
UpdateInfo;
|
||||
end;
|
||||
|
||||
procedure TBreakPropertyDlg.edtDisableGroupsButtonClick(Sender: TObject);
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
procedure TBreakPropertyDlg.edtEnableGroupsButtonClick(Sender: TObject);
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
procedure TBreakPropertyDlg.UpdateInfo;
|
||||
var
|
||||
Actions: TIDEBreakPointActions;
|
||||
begin
|
||||
if FBreakpoint = nil then Exit;
|
||||
// filename
|
||||
edtFilename.text := FBreakpoint.Source;
|
||||
// line
|
||||
if FBreakpoint.Line > 0
|
||||
then edtLine.Text := IntToStr(FBreakpoint.SourceLine)
|
||||
else edtLine.Text := '';
|
||||
// expression
|
||||
edtCondition.Text := FBreakpoint.Expression;
|
||||
// hitcount
|
||||
edtCounter.Text := IntToStr(FBreakpoint.BreakHitCount);
|
||||
// auto continue
|
||||
edtAutocontinueMS.Text := IntToStr(FBreakpoint.AutoContinueTime);
|
||||
// group
|
||||
if FBreakpoint.Group = nil
|
||||
then cmbGroup.Text := ''
|
||||
else cmbGroup.Text := FBreakpoint.Group.Name;
|
||||
|
||||
// actions
|
||||
Actions := FBreakpoint.Actions;
|
||||
chkActionBreak.Checked := bpaStop in Actions;
|
||||
chkDisableGroups.Checked := bpaDisableGroup in Actions;
|
||||
chkEnableGroups.Checked := bpaEnableGroup in Actions;
|
||||
// chkEvalExpression.Checked := bpaEValExpression in Actions;
|
||||
// chkLogMessage.Checked := bpaLogMessage in Actions;
|
||||
end;
|
||||
|
||||
constructor TBreakPropertyDlg.Create(AOwner: TComponent; ABreakPoint: TIDEBreakPoint);
|
||||
begin
|
||||
inherited Create(AOwner);
|
||||
FBreakpoint := ABreakPoint;
|
||||
FBreakpointsNotification := TIDEBreakPointsNotification.Create;
|
||||
FBreakpointsNotification.AddReference;
|
||||
FBreakpointsNotification.OnUpdate := @BreakPointUpdate;
|
||||
FBreakpointsNotification.OnRemove := @BreakPointRemove;
|
||||
UpdateInfo;
|
||||
|
||||
btnOK.LoadGlyphFromLazarusResource('btn_ok');
|
||||
btnCancel.LoadGlyphFromLazarusResource('btn_cancel');
|
||||
btnHelp.LoadGlyphFromLazarusResource('btn_help');
|
||||
end;
|
||||
|
||||
destructor TBreakPropertyDlg.Destroy;
|
||||
begin
|
||||
FBreakpointsNotification.OnUpdate := nil;
|
||||
FBreakpointsNotification.OnRemove := nil;
|
||||
FBreakpointsNotification.ReleaseReference;
|
||||
FBreakpointsNotification := nil;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
initialization
|
||||
{$I breakpropertydlg.lrs}
|
||||
|
||||
end.
|
||||
|
@ -68,7 +68,7 @@ type
|
||||
dcDisassemble
|
||||
);
|
||||
TDBGCommands = set of TDBGCommand;
|
||||
|
||||
|
||||
TDBGState = (
|
||||
dsNone,
|
||||
dsIdle,
|
||||
@ -78,7 +78,7 @@ type
|
||||
dsRun,
|
||||
dsError
|
||||
);
|
||||
|
||||
|
||||
{
|
||||
Debugger states
|
||||
--------------------------------------------------------------------------
|
||||
@ -143,7 +143,7 @@ type
|
||||
destructor Destroy; override;
|
||||
procedure ReleaseReference;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
TIDEBreakPoints = class;
|
||||
TIDEBreakPointGroup = class;
|
||||
@ -178,26 +178,30 @@ type
|
||||
bpaDisableGroup
|
||||
);
|
||||
TIDEBreakPointActions = set of TIDEBreakPointAction;
|
||||
|
||||
|
||||
{ TBaseBreakPoint }
|
||||
|
||||
TBaseBreakPoint = class(TDelayedUdateItem)
|
||||
private
|
||||
FEnabled: Boolean;
|
||||
FExpression: String;
|
||||
FHitCount: Integer;
|
||||
FBreakHitCount: Integer;
|
||||
FLine: Integer;
|
||||
FSource: String;
|
||||
FValid: TValidState;
|
||||
FInitialEnabled: Boolean;
|
||||
protected
|
||||
procedure AssignTo(Dest: TPersistent); override;
|
||||
procedure DoBreakHitCountChange; virtual;
|
||||
procedure DoExpressionChange; virtual;
|
||||
procedure DoEnableChange; virtual;
|
||||
procedure DoHit(const ACount: Integer; var AContinue: Boolean); virtual;
|
||||
procedure SetHitCount(const AValue: Integer);
|
||||
procedure SetValid(const AValue: TValidState);
|
||||
|
||||
protected
|
||||
// virtual properties
|
||||
function GetBreakHitCount: Integer; virtual;
|
||||
function GetEnabled: Boolean; virtual;
|
||||
function GetExpression: String; virtual;
|
||||
function GetHitCount: Integer; virtual;
|
||||
@ -206,12 +210,14 @@ type
|
||||
function GetSourceLine: Integer; virtual;
|
||||
function GetValid: TValidState; virtual;
|
||||
|
||||
procedure SetBreakHitCount(const AValue: Integer); virtual;
|
||||
procedure SetEnabled(const AValue: Boolean); virtual;
|
||||
procedure SetExpression(const AValue: String); virtual;
|
||||
procedure SetInitialEnabled(const AValue: Boolean); virtual;
|
||||
public
|
||||
constructor Create(ACollection: TCollection); override;
|
||||
procedure SetLocation(const ASource: String; const ALine: Integer); virtual;// PublicProtectedFix ide/debugmanager.pas(867,32) Error: identifier idents no member "SetLocation"
|
||||
property BreakHitCount: Integer read GetBreakHitCount write SetBreakHitCount;
|
||||
property Enabled: Boolean read GetEnabled write SetEnabled;
|
||||
property Expression: String read GetExpression write SetExpression;
|
||||
property HitCount: Integer read GetHitCount;
|
||||
@ -227,6 +233,7 @@ type
|
||||
|
||||
TIDEBreakPoint = class(TBaseBreakPoint)
|
||||
private
|
||||
FAutoContinueTime: Cardinal;
|
||||
FActions: TIDEBreakPointActions;
|
||||
FDisableGroupList: TList;
|
||||
FEnableGroupList: TList;
|
||||
@ -246,8 +253,10 @@ type
|
||||
// virtual properties
|
||||
function GetActions: TIDEBreakPointActions; virtual;
|
||||
function GetGroup: TIDEBreakPointGroup; virtual;
|
||||
function GetAutoContinueTime: Cardinal; virtual;
|
||||
procedure SetActions(const AValue: TIDEBreakPointActions); virtual;
|
||||
procedure SetGroup(const AValue: TIDEBreakPointGroup); virtual;
|
||||
procedure SetAutoContinueTime(const AValue: Cardinal); virtual;
|
||||
public
|
||||
constructor Create(ACollection: TCollection); override;
|
||||
destructor Destroy; override;
|
||||
@ -262,11 +271,14 @@ type
|
||||
const OnSaveFilename: TOnSaveFilenameToConfig); virtual;
|
||||
public
|
||||
property Actions: TIDEBreakPointActions read GetActions write SetActions;
|
||||
property AutoContinueTime: Cardinal read GetAutoContinueTime write SetAutoContinueTime;
|
||||
property Group: TIDEBreakPointGroup read GetGroup write SetGroup;
|
||||
property Loading: Boolean read FLoading;
|
||||
end;
|
||||
TIDEBreakPointClass = class of TIDEBreakPoint;
|
||||
|
||||
{ TDBGBreakPoint }
|
||||
|
||||
TDBGBreakPoint = class(TBaseBreakPoint)
|
||||
private
|
||||
FSlave: TBaseBreakPoint;
|
||||
@ -280,6 +292,7 @@ type
|
||||
constructor Create(ACollection: TCollection); override;
|
||||
destructor Destroy; override;
|
||||
function GetSourceLine: integer; override;
|
||||
procedure Hit(var ACanContinue: Boolean);
|
||||
property Slave: TBaseBreakPoint read FSlave write SetSlave;
|
||||
end;
|
||||
TDBGBreakPointClass = class of TDBGBreakPoint;
|
||||
@ -337,7 +350,7 @@ type
|
||||
property Items[const AnIndex: Integer]: TIDEBreakPoint read GetItem
|
||||
write SetItem; default;
|
||||
end;
|
||||
|
||||
|
||||
TDBGBreakPoints = class(TBaseBreakPoints)
|
||||
private
|
||||
FDebugger: TDebugger; // reference to our debugger
|
||||
@ -419,8 +432,8 @@ type
|
||||
property Items[const AnIndex: Integer]: TIDEBreakPointGroup
|
||||
read GetItem write SetItem; default;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
|
||||
(******************************************************************************)
|
||||
(******************************************************************************)
|
||||
(** **)
|
||||
@ -442,7 +455,7 @@ type
|
||||
procedure DoEnableChange; virtual;
|
||||
procedure DoExpressionChange; virtual;
|
||||
procedure SetValid(const AValue: TValidState);
|
||||
|
||||
|
||||
protected
|
||||
// virtual properties
|
||||
function GetExpression: String; virtual;
|
||||
@ -460,7 +473,7 @@ type
|
||||
property Value: String read GetValue;
|
||||
end;
|
||||
TBaseWatchClass = class of TBaseWatch;
|
||||
|
||||
|
||||
TIDEWatch = class(TBaseWatch)
|
||||
private
|
||||
protected
|
||||
@ -498,7 +511,7 @@ type
|
||||
|
||||
TIDEWatchesEvent =
|
||||
procedure(const ASender: TIDEWatches; const AWatch: TIDEWatch) of object;
|
||||
|
||||
|
||||
TIDEWatchesNotification = class(TDebuggerNotification)
|
||||
private
|
||||
FOnAdd: TIDEWatchesEvent;
|
||||
@ -519,7 +532,7 @@ type
|
||||
function Find(const AExpression: String): TBaseWatch;
|
||||
// no items property needed, it is "overridden" anyhow
|
||||
end;
|
||||
|
||||
|
||||
TIDEWatches = class(TBaseWatches)
|
||||
private
|
||||
FNotificationList: TList;
|
||||
@ -568,7 +581,7 @@ type
|
||||
write SetItem; default;
|
||||
property OnChange: TNotifyEvent read FOnChange write FOnChange;
|
||||
end;
|
||||
|
||||
|
||||
(******************************************************************************)
|
||||
(******************************************************************************)
|
||||
(** **)
|
||||
@ -630,8 +643,8 @@ type
|
||||
constructor Create(const ADebugger: TDebugger);
|
||||
property OnChange: TNotifyEvent read FOnChange write FOnChange;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
|
||||
(******************************************************************************)
|
||||
(******************************************************************************)
|
||||
(** **)
|
||||
@ -722,7 +735,7 @@ type
|
||||
FLine: Integer;
|
||||
FArguments: TStrings;
|
||||
FSource: String;
|
||||
function GetArgumentCount: Integer;
|
||||
function GetArgumentCount: Integer;
|
||||
function GetArgumentName(const AnIndex: Integer): String;
|
||||
function GetArgumentValue(const AnIndex: Integer): String;
|
||||
function GetCurrent: Boolean;
|
||||
@ -743,7 +756,7 @@ type
|
||||
property Line: Integer read FLine;
|
||||
property Source: String read FSource;
|
||||
end;
|
||||
|
||||
|
||||
{ TBaseCallStack }
|
||||
|
||||
TBaseCallStack = class(TObject)
|
||||
@ -765,7 +778,7 @@ type
|
||||
property Current: TCallStackEntry read GetCurrent write SetCurrent;
|
||||
property Entries[AIndex: Integer]: TCallStackEntry read GetEntry;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
{ TIDECallStackNotification }
|
||||
|
||||
@ -854,9 +867,9 @@ type
|
||||
property ResumeHandled: Boolean read FResumeHandled write SetResumeHandled;
|
||||
end;
|
||||
TBaseSignalClass = class of TBaseSignal;
|
||||
|
||||
|
||||
{ TDBGSignal }
|
||||
|
||||
|
||||
TDBGSignal = class(TBaseSignal)
|
||||
private
|
||||
function GetDebugger: TDebugger;
|
||||
@ -865,7 +878,7 @@ type
|
||||
public
|
||||
end;
|
||||
TDBGSignalClass = class of TDBGSignal;
|
||||
|
||||
|
||||
TIDESignal = class(TBaseSignal)
|
||||
private
|
||||
protected
|
||||
@ -906,7 +919,7 @@ type
|
||||
end;
|
||||
|
||||
{ TIDESignals }
|
||||
|
||||
|
||||
TIDESignals = class(TBaseSignals)
|
||||
private
|
||||
function GetItem(const AIndex: Integer): TIDESignal;
|
||||
@ -1028,6 +1041,8 @@ type
|
||||
|
||||
TDebuggerStateChangedEvent = procedure(ADebugger: TDebugger;
|
||||
AOldState: TDBGState) of object;
|
||||
TDebuggerBreakPointHitEvent = procedure(ADebugger: TDebugger; ABreakPoint: TBaseBreakPoint;
|
||||
var ACanContinue: Boolean) of object;
|
||||
TDBGOutputEvent = procedure(Sender: TObject; const AText: String) of object;
|
||||
TDBGCurrentLineEvent = procedure(Sender: TObject;
|
||||
const ALocation: TDBGLocationRec) of object;
|
||||
@ -1064,6 +1079,7 @@ type
|
||||
FOnOutput: TDBGOutputEvent;
|
||||
FOnDbgOutput: TDBGOutputEvent;
|
||||
FOnState: TDebuggerStateChangedEvent;
|
||||
FOnBreakPointHit: TDebuggerBreakPointHitEvent;
|
||||
FWorkingDir: String;
|
||||
procedure DebuggerEnvironmentChanged(Sender: TObject);
|
||||
procedure EnvironmentChanged(Sender: TObject);
|
||||
@ -1085,6 +1101,7 @@ type
|
||||
procedure DoDbgOutput(const AText: String);
|
||||
procedure DoException(const AExceptionClass: String; const AExceptionText: String);
|
||||
procedure DoOutput(const AText: String);
|
||||
procedure DoBreakpointHit(const ABreakPoint: TBaseBreakPoint; var ACanContinue: Boolean);
|
||||
procedure DoState(const OldState: TDBGState); virtual;
|
||||
function ChangeFileName: Boolean; virtual;
|
||||
function GetCommands: TDBGCommands;
|
||||
@ -1153,9 +1170,10 @@ type
|
||||
property OnException: TDBGExceptionEvent read FOnException write FOnException; // Fires when the debugger received an exeption
|
||||
property OnOutput: TDBGOutputEvent read FOnOutput write FOnOutput; // Passes all output of the debugged target
|
||||
property OnState: TDebuggerStateChangedEvent read FOnState write FOnState; // Fires when the current state of the debugger changes
|
||||
property OnBreakPointHit: TDebuggerBreakPointHitEvent read FOnBreakPointHit write FOnBreakPointHit; // Fires when the program is paused at a breakpoint
|
||||
end;
|
||||
TDebuggerClass = class of TDebugger;
|
||||
|
||||
|
||||
const
|
||||
DBGCommandNames: array[TDBGCommand] of string = (
|
||||
'Run',
|
||||
@ -1174,7 +1192,7 @@ const
|
||||
'SetStackFrame',
|
||||
'Disassemble'
|
||||
);
|
||||
|
||||
|
||||
DBGStateNames: array[TDBGState] of string = (
|
||||
'None',
|
||||
'Idle',
|
||||
@ -1184,13 +1202,13 @@ const
|
||||
'Run',
|
||||
'Error'
|
||||
);
|
||||
|
||||
|
||||
DBGBreakPointActionNames: array[TIDEBreakPointAction] of string = (
|
||||
'Stop',
|
||||
'EnableGroup',
|
||||
'DisableGroup'
|
||||
);
|
||||
|
||||
|
||||
function DBGCommandNameToCommand(const s: string): TDBGCommand;
|
||||
function DBGStateNameToState(const s: string): TDBGState;
|
||||
function DBGBreakPointActionNameToAction(const s: string): TIDEBreakPointAction;
|
||||
@ -1217,7 +1235,7 @@ const
|
||||
{dsRun } [dcPause, dcStop, dcBreak, dcWatch, dcEnvironment],
|
||||
{dsError} [dcStop]
|
||||
);
|
||||
|
||||
|
||||
var
|
||||
MDebuggerPropertiesList: TStringlist;
|
||||
|
||||
@ -1334,7 +1352,7 @@ begin
|
||||
Result := TDBGBreakPoints.Create(Self, TDBGBreakPoint);
|
||||
end;
|
||||
|
||||
function TDebugger.CreateCallStack: TDBGCallStack;
|
||||
function TDebugger.CreateCallStack: TDBGCallStack;
|
||||
begin
|
||||
Result := TDBGCallStack.Create(Self);
|
||||
end;
|
||||
@ -1349,7 +1367,7 @@ begin
|
||||
Result := TDBGLocals.Create(Self);
|
||||
end;
|
||||
|
||||
class function TDebugger.CreateProperties: TDebuggerProperties;
|
||||
class function TDebugger.CreateProperties: TDebuggerProperties;
|
||||
begin
|
||||
Result := TDebuggerProperties.Create;
|
||||
end;
|
||||
@ -1421,7 +1439,7 @@ begin
|
||||
end;
|
||||
|
||||
procedure TDebugger.DoDbgOutput(const AText: String);
|
||||
begin
|
||||
begin
|
||||
// WriteLN(' [TDebugger] ', AText);
|
||||
if Assigned(FOnDbgOutput) then FOnDbgOutput(Self, AText);
|
||||
end;
|
||||
@ -1438,6 +1456,12 @@ begin
|
||||
if Assigned(FOnOutput) then FOnOutput(Self, AText);
|
||||
end;
|
||||
|
||||
procedure TDebugger.DoBreakpointHit(const ABreakPoint: TBaseBreakPoint; var ACanContinue: Boolean);
|
||||
begin
|
||||
if Assigned(FOnBreakpointHit)
|
||||
then FOnBreakpointHit(Self, ABreakPoint, ACanContinue);
|
||||
end;
|
||||
|
||||
procedure TDebugger.DoState(const OldState: TDBGState);
|
||||
begin
|
||||
if State in INTERNAL_STATES then Exit;
|
||||
@ -1469,7 +1493,7 @@ begin
|
||||
then Env.Delete(idx);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
// Set the remaining
|
||||
for n := 0 to Env.Count - 1 do
|
||||
begin
|
||||
@ -1567,7 +1591,7 @@ function TDebugger.ReqCmd(const ACommand: TDBGCommand;
|
||||
const AParams: array of const): Boolean;
|
||||
begin
|
||||
if FState = dsNone then Init;
|
||||
if ACommand in Commands
|
||||
if ACommand in Commands
|
||||
then begin
|
||||
Result := RequestCommand(ACommand, AParams);
|
||||
if not Result then begin
|
||||
@ -1618,7 +1642,7 @@ begin
|
||||
if FState <> dsStop
|
||||
then SetState(dsError);
|
||||
end;
|
||||
|
||||
|
||||
if FState = dsStop
|
||||
then begin
|
||||
// Reset state
|
||||
@ -1651,7 +1675,7 @@ var
|
||||
begin
|
||||
if AValue <> FState
|
||||
then begin
|
||||
OldState := FState;
|
||||
OldState := FState;
|
||||
FState := AValue;
|
||||
FBreakpoints.DoStateChange(OldState);
|
||||
FLocals.DoStateChange(OldState);
|
||||
@ -1694,12 +1718,12 @@ end;
|
||||
|
||||
procedure TBaseBreakPoint.AssignTo(Dest: TPersistent);
|
||||
var
|
||||
DestBreakPoint: TBaseBreakPoint;
|
||||
DestBreakPoint: TBaseBreakPoint absolute Dest;
|
||||
begin
|
||||
// updatelock is set in source.assignto
|
||||
if Dest is TBaseBreakPoint
|
||||
then begin
|
||||
DestBreakPoint:=TBaseBreakPoint(Dest);
|
||||
DestBreakPoint.SetBreakHitCount(FBreakHitCount);
|
||||
DestBreakPoint.SetLocation(FSource, FLine);
|
||||
DestBreakPoint.SetExpression(FExpression);
|
||||
DestBreakPoint.SetEnabled(FEnabled);
|
||||
@ -1715,11 +1739,17 @@ begin
|
||||
FValid := vsUnknown;
|
||||
FEnabled := False;
|
||||
FHitCount := 0;
|
||||
FBreakHitCount := 0;
|
||||
FExpression := '';
|
||||
FInitialEnabled := False;
|
||||
inherited Create(ACollection);
|
||||
end;
|
||||
|
||||
procedure TBaseBreakPoint.DoBreakHitCountChange;
|
||||
begin
|
||||
Changed;
|
||||
end;
|
||||
|
||||
procedure TBaseBreakPoint.DoEnableChange;
|
||||
begin
|
||||
Changed;
|
||||
@ -1735,6 +1765,11 @@ begin
|
||||
SetHitCount(ACount);
|
||||
end;
|
||||
|
||||
function TBaseBreakPoint.GetBreakHitCount: Integer;
|
||||
begin
|
||||
Result := FBreakHitCount;
|
||||
end;
|
||||
|
||||
function TBaseBreakPoint.GetEnabled: Boolean;
|
||||
begin
|
||||
Result := FEnabled;
|
||||
@ -1770,6 +1805,15 @@ begin
|
||||
Result := FValid;
|
||||
end;
|
||||
|
||||
procedure TBaseBreakPoint.SetBreakHitCount(const AValue: Integer);
|
||||
begin
|
||||
if FBreakHitCount <> AValue
|
||||
then begin
|
||||
FBreakHitCount := AValue;
|
||||
DoBreakHitCountChange;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TBaseBreakPoint.SetEnabled (const AValue: Boolean );
|
||||
begin
|
||||
if FEnabled <> AValue
|
||||
@ -1840,12 +1884,25 @@ begin
|
||||
Changed;
|
||||
end;
|
||||
|
||||
function TIDEBreakPoint.GetAutoContinueTime: Cardinal;
|
||||
begin
|
||||
Result := FAutoContinueTime;
|
||||
end;
|
||||
|
||||
procedure TIDEBreakPoint.SetAutoContinueTime(const AValue: Cardinal);
|
||||
begin
|
||||
if FAutoContinueTime = AValue then Exit;
|
||||
FAutoContinueTime := AValue;
|
||||
Changed;
|
||||
end;
|
||||
|
||||
procedure TIDEBreakPoint.AssignTo(Dest: TPersistent);
|
||||
begin
|
||||
inherited;
|
||||
if Dest is TIDEBreakPoint
|
||||
then begin
|
||||
TIDEBreakPoint(Dest).Actions := FActions;
|
||||
TIDEBreakPoint(Dest).AutoContinueTime := FAutoContinueTime;
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -1967,6 +2024,8 @@ begin
|
||||
GroupName:=XMLConfig.GetValue(Path+'Group/Name','');
|
||||
Group:=OnGetGroup(GroupName);
|
||||
Expression:=XMLConfig.GetValue(Path+'Expression/Value','');
|
||||
AutoContinueTime:=XMLConfig.GetValue(Path+'AutoContinueTime/Value',0);
|
||||
BreakHitCount := XMLConfig.GetValue(Path+'BreakHitCount/Value',0);
|
||||
Filename:=XMLConfig.GetValue(Path+'Source/Value','');
|
||||
if Assigned(OnLoadFilename) then OnLoadFilename(Filename);
|
||||
FSource:=Filename;
|
||||
@ -2008,7 +2067,7 @@ end;
|
||||
|
||||
procedure TIDEBreakPoint.SaveToXMLConfig(const AConfig: TXMLConfig;
|
||||
const APath: string; const OnSaveFilename: TOnSaveFilenameToConfig);
|
||||
|
||||
|
||||
procedure SaveGroupList(const AList: TList; const AListPath: string);
|
||||
var
|
||||
i: Integer;
|
||||
@ -2022,19 +2081,21 @@ procedure TIDEBreakPoint.SaveToXMLConfig(const AConfig: TXMLConfig;
|
||||
CurGroup.Name, '');
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
var
|
||||
Filename: String;
|
||||
CurAction: TIDEBreakPointAction;
|
||||
begin
|
||||
if Group <> nil
|
||||
then AConfig.SetDeleteValue(APath+'Group/Name',Group.Name,'');
|
||||
|
||||
|
||||
AConfig.SetDeleteValue(APath+'Expression/Value',Expression,'');
|
||||
AConfig.SetDeleteValue(APath+'AutoContinueTime/Value',AutoContinueTime,0);
|
||||
AConfig.SetDeleteValue(APath+'BreakHitCount/Value',BreakHitCount,0);
|
||||
|
||||
Filename := Source;
|
||||
if Assigned(OnSaveFilename) then OnSaveFilename(Filename);
|
||||
|
||||
|
||||
AConfig.SetDeleteValue(APath+'Source/Value',Filename,'');
|
||||
AConfig.SetDeleteValue(APath+'InitialEnabled/Value',InitialEnabled,true);
|
||||
AConfig.SetDeleteValue(APath+'Line/Value',Line,-1);
|
||||
@ -2134,6 +2195,17 @@ begin
|
||||
Result:=inherited GetSourceLine;
|
||||
end;
|
||||
|
||||
procedure TDBGBreakPoint.Hit(var ACanContinue: Boolean);
|
||||
var
|
||||
cnt: Integer;
|
||||
begin
|
||||
cnt := HitCount + 1;
|
||||
if BreakHitcount > 0
|
||||
then ACanContinue := cnt < BreakHitcount;
|
||||
DoHit(cnt, ACanContinue);
|
||||
Debugger.DoBreakpointHit(Self, ACanContinue)
|
||||
end;
|
||||
|
||||
procedure TDBGBreakPoint.DoChanged;
|
||||
begin
|
||||
inherited DoChanged;
|
||||
@ -2270,13 +2342,13 @@ begin
|
||||
LoadBreakPoint := TIDEBreakPoint.Create(nil);
|
||||
LoadBreakPoint.LoadFromXMLConfig(XMLConfig,
|
||||
Path+'Item'+IntToStr(i+1)+'/',OnLoadFilename,OnGetGroup);
|
||||
|
||||
|
||||
BreakPoint := Find(LoadBreakPoint.Source, LoadBreakPoint.Line, LoadBreakPoint);
|
||||
|
||||
if BreakPoint = nil
|
||||
then BreakPoint := Add(LoadBreakPoint.Source, LoadBreakPoint.Line);
|
||||
BreakPoint.Assign(LoadBreakPoint);
|
||||
|
||||
|
||||
FreeAndNil(LoadBreakPoint)
|
||||
end;
|
||||
end;
|
||||
@ -2674,7 +2746,7 @@ begin
|
||||
end;
|
||||
|
||||
function TBaseWatch.GetValue: String;
|
||||
begin
|
||||
begin
|
||||
if not Enabled
|
||||
then Result := '<disabled>'
|
||||
else begin
|
||||
@ -2942,7 +3014,7 @@ begin
|
||||
begin
|
||||
Notification := TIDEWatchesNotification(FNotificationList[n]);
|
||||
if not Assigned(Notification.FOnUpdate) then Continue;
|
||||
|
||||
|
||||
if Item = nil
|
||||
then begin
|
||||
for m := 0 to Count - 1 do
|
||||
@ -3254,7 +3326,7 @@ constructor TCallStackEntry.Create(const AIndex: Integer;
|
||||
const AnAdress: TDbgPtr; const AnArguments: TStrings;
|
||||
const AFunctionName: String; const ASource: String; const ALine: Integer);
|
||||
begin
|
||||
inherited Create;
|
||||
inherited Create;
|
||||
FIndex := AIndex;
|
||||
FAdress := AnAdress;
|
||||
FArguments := TStringlist.Create;
|
||||
@ -3287,7 +3359,7 @@ begin
|
||||
end;
|
||||
|
||||
function TCallStackEntry.GetArgumentValue(const AnIndex: Integer): String;
|
||||
begin
|
||||
begin
|
||||
Result := FArguments[AnIndex];
|
||||
Result := GetPart('=', '', Result);
|
||||
end;
|
||||
@ -3301,7 +3373,7 @@ procedure TCallStackEntry.SetCurrent(const AValue: Boolean);
|
||||
begin
|
||||
if FOwner = nil then Exit;
|
||||
if GetCurrent = AValue then Exit;
|
||||
|
||||
|
||||
if AValue
|
||||
then FOwner.SetCurrent(self)
|
||||
else FOwner.SetCurrent(nil);
|
||||
@ -3502,12 +3574,12 @@ begin
|
||||
Changed;
|
||||
end
|
||||
else begin
|
||||
if (AOldState = dsPause) or (AOldState = dsNone) { Force clear on initialisation }
|
||||
then begin
|
||||
if (AOldState = dsPause) or (AOldState = dsNone) { Force clear on initialisation }
|
||||
then begin
|
||||
Clear;
|
||||
if Assigned(FOnClear) then FOnClear(Self);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TDBGCallStack.InternalGetEntry(AIndex: Integer): TCallStackEntry;
|
||||
@ -3790,7 +3862,7 @@ end;
|
||||
procedure TBaseException.SetName(const AValue: String);
|
||||
begin
|
||||
if FName = AValue then exit;
|
||||
|
||||
|
||||
if TBaseExceptions(GetOwner).Find(AValue) <> nil
|
||||
then raise EDBGExceptions.Create('Duplicate name: ' + AValue);
|
||||
|
||||
|
@ -1,16 +1,16 @@
|
||||
{ $Id$ }
|
||||
{ ----------------------------------------
|
||||
{ ----------------------------------------
|
||||
DebuggerDlg.pp - Base class for all
|
||||
debugger related forms
|
||||
----------------------------------------
|
||||
|
||||
----------------------------------------
|
||||
|
||||
@created(Wed Mar 16st WET 2001)
|
||||
@lastmod($Date$)
|
||||
@author(Marc Weustink <marc@@dommelstein.net>)
|
||||
@author(Marc Weustink <marc@@dommelstein.net>)
|
||||
|
||||
This unit contains the base class for all debugger related dialogs.
|
||||
This unit contains the base class for all debugger related dialogs.
|
||||
All common info needed for the IDE is found in this class
|
||||
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* This source is free software; you can redistribute it and/or modify *
|
||||
@ -37,15 +37,15 @@ unit DebuggerDlg;
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, Forms, Controls, IDEProcs, Debugger, EnvironmentOpts;
|
||||
Classes, Forms, Controls, IDEProcs, Debugger, EnvironmentOpts, IDEOptionDefs;
|
||||
|
||||
type
|
||||
TDebuggerDlgClass = class of TDebuggerDlg;
|
||||
|
||||
|
||||
TDebuggerDlg = class(TForm)
|
||||
private
|
||||
FUpdateCount: integer;
|
||||
protected
|
||||
protected
|
||||
procedure DoClose(var CloseAction: TCloseAction); override;
|
||||
procedure DoBeginUpdate; virtual;
|
||||
procedure DoEndUpdate; virtual;
|
||||
@ -55,10 +55,10 @@ type
|
||||
function UpdateCount: integer;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TDebuggerDlg }
|
||||
|
||||
implementation
|
||||
|
||||
{ TDebuggerDlg }
|
||||
|
||||
procedure TDebuggerDlg.BeginUpdate;
|
||||
begin
|
||||
Inc(FUpdateCount);
|
||||
@ -80,24 +80,25 @@ end;
|
||||
(*
|
||||
procedure TDebuggerDlg.SetDebugger(const ADebugger: TDebugger);
|
||||
begin
|
||||
FDebugger := ADebugger;
|
||||
FDebugger := ADebugger;
|
||||
end;
|
||||
*)
|
||||
procedure TDebuggerDlg.DoClose(var CloseAction: TCloseAction);
|
||||
var
|
||||
Layout: TIDEWindowLayout;
|
||||
begin
|
||||
CloseAction := caFree; // we default to free
|
||||
inherited DoClose(CloseAction);
|
||||
EnvironmentOptions.IDEWindowLayoutList.ItemByFormID(Name).GetCurrentPosition;
|
||||
Layout := EnvironmentOptions.IDEWindowLayoutList.ItemByFormID(Name);
|
||||
if Layout <> nil then Layout.GetCurrentPosition;
|
||||
end;
|
||||
|
||||
procedure TDebuggerDlg.DoBeginUpdate;
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
procedure TDebuggerDlg.DoEndUpdate;
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
end.
|
||||
|
@ -67,7 +67,7 @@ type
|
||||
// some MI functions return normal output
|
||||
// some normal functions return MI output
|
||||
);
|
||||
|
||||
|
||||
TGDBMIExecResult = record
|
||||
State: TDBGState;
|
||||
Values: String;
|
||||
@ -198,13 +198,13 @@ type
|
||||
class function CreateProperties: TDebuggerProperties; override; // Creates debuggerproperties
|
||||
class function Caption: String; override;
|
||||
class function ExePaths: String; override;
|
||||
|
||||
|
||||
constructor Create(const AExternalDebugger: String); override;
|
||||
destructor Destroy; override;
|
||||
|
||||
procedure Init; override; // Initializes external debugger
|
||||
procedure Done; override; // Kills external debugger
|
||||
|
||||
|
||||
// internal testing
|
||||
procedure TestCmd(const ACommand: String); override;
|
||||
end;
|
||||
@ -268,7 +268,6 @@ type
|
||||
public
|
||||
constructor Create(ACollection: TCollection); override;
|
||||
destructor Destroy; override;
|
||||
procedure Hit(var ACanContinue: Boolean);
|
||||
procedure SetLocation(const ASource: String; const ALine: Integer); override;
|
||||
end;
|
||||
|
||||
@ -334,7 +333,7 @@ type
|
||||
constructor Create(ACollection: TCollection); override;
|
||||
procedure Invalidate;
|
||||
end;
|
||||
|
||||
|
||||
{ TDBGWatches }
|
||||
|
||||
{ TGDBMIWatches }
|
||||
@ -345,7 +344,7 @@ type
|
||||
procedure Changed;
|
||||
public
|
||||
end;
|
||||
|
||||
|
||||
{ TGDBMICallStack }
|
||||
|
||||
TGDBMICallStack = class(TDBGCallStack)
|
||||
@ -363,7 +362,7 @@ type
|
||||
|
||||
TGDBMIExpression = class(TObject)
|
||||
private
|
||||
FDebugger: TGDBMIDebugger;
|
||||
FDebugger: TGDBMIDebugger;
|
||||
FOperator: String;
|
||||
FLeft: TGDBMIExpression;
|
||||
FRight: TGDBMIExpression;
|
||||
@ -375,7 +374,7 @@ type
|
||||
function DumpExpression: String;
|
||||
function GetExpression(var AResult: String): Boolean;
|
||||
end;
|
||||
|
||||
|
||||
{ TGDBMIType }
|
||||
|
||||
TGDBMIType = class(TGDBType)
|
||||
@ -661,11 +660,11 @@ var
|
||||
procedure InitWin32;
|
||||
var
|
||||
hMod: THandle;
|
||||
begin
|
||||
begin
|
||||
// Check if we already are initialized
|
||||
if DebugBreakAddr <> nil then Exit;
|
||||
|
||||
// normally you would load a lib, but since kernel32 is
|
||||
|
||||
// normally you would load a lib, but since kernel32 is
|
||||
// always loaded we can use this (and we don't have to free it
|
||||
hMod := GetModuleHandle(kernel32);
|
||||
if hMod = 0 then Exit; //????
|
||||
@ -673,7 +672,7 @@ begin
|
||||
DebugBreakAddr := GetProcAddress(hMod, 'DebugBreak');
|
||||
Pointer(_CreateRemoteThread) := GetProcAddress(hMod, 'CreateRemoteThread');
|
||||
end;
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
|
||||
{ =========================================================================== }
|
||||
{ Helpers }
|
||||
@ -685,14 +684,14 @@ begin
|
||||
Result := APath;
|
||||
// no need to process empty filename
|
||||
if Result='' then exit;
|
||||
|
||||
|
||||
{$WARNINGS off}
|
||||
if DirectorySeparator <> '/' then
|
||||
Result := StringReplace(Result, DirectorySeparator, '/', [rfReplaceAll]);
|
||||
{$WARNINGS on}
|
||||
Result := '"' + Result + '"';
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
{ =========================================================================== }
|
||||
{ TGDBMIDebuggerProperties }
|
||||
{ =========================================================================== }
|
||||
@ -713,7 +712,7 @@ begin
|
||||
if FCurrentStackFrame = AIndex then Exit;
|
||||
FCurrentStackFrame := AIndex;
|
||||
SelectStackFrame(FCurrentStackFrame);
|
||||
|
||||
|
||||
TGDBMICallstack(CallStack).CurrentChanged;
|
||||
TGDBMILocals(Locals).Changed;
|
||||
TGDBMIWatches(Watches).Changed;
|
||||
@ -737,14 +736,14 @@ var
|
||||
List: TGDBMINameValueList;
|
||||
begin
|
||||
Result := False;
|
||||
|
||||
|
||||
//Cleanup our own breakpoints
|
||||
ClearBreakpoint(FExceptionBreakID);
|
||||
ClearBreakpoint(FBreakErrorBreakID);
|
||||
ClearBreakpoint(FRunErrorBreakID);
|
||||
|
||||
|
||||
S := ConvertToGDBPath(UTF8ToSys(FileName));
|
||||
S := ConvertToGDBPath(UTF8ToSys(FileName));
|
||||
if not ExecuteCommand('-file-exec-and-symbols %s', [S], [cfIgnoreError], R) then Exit;
|
||||
if (R.State = dsError)
|
||||
and (FileName <> '')
|
||||
@ -757,12 +756,12 @@ begin
|
||||
end;
|
||||
if not (inherited ChangeFileName) then Exit;
|
||||
if State = dsError then Exit;
|
||||
if FileName = ''
|
||||
if FileName = ''
|
||||
then begin
|
||||
Result := True;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
|
||||
if tfHasSymbols in FTargetFlags
|
||||
then begin
|
||||
// Force setting language
|
||||
@ -796,7 +795,7 @@ begin
|
||||
|
||||
{$IFdef MSWindows}
|
||||
InitWin32;
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
|
||||
inherited;
|
||||
end;
|
||||
@ -806,7 +805,7 @@ begin
|
||||
Result := TDBGBreakPoints.Create(Self, TGDBMIBreakPoint);
|
||||
end;
|
||||
|
||||
function TGDBMIDebugger.CreateCallStack: TDBGCallStack;
|
||||
function TGDBMIDebugger.CreateCallStack: TDBGCallStack;
|
||||
begin
|
||||
Result := TGDBMICallStack.Create(Self);
|
||||
end;
|
||||
@ -938,7 +937,7 @@ begin
|
||||
ExecResult.Values := '';
|
||||
ExecResult.State := dsNone;
|
||||
ExecResult.Flags := [];
|
||||
|
||||
|
||||
Cmd := FCommandQueue[0];
|
||||
CmdInfo := PGDBMICmdInfo(FCommandQueue.Objects[0]);
|
||||
SendCmdLn(Cmd);
|
||||
@ -980,7 +979,7 @@ begin
|
||||
finally
|
||||
Dec(FInExecuteCount);
|
||||
end;
|
||||
|
||||
|
||||
if FCommandQueue.Count = 0
|
||||
then begin
|
||||
if (FInExecuteCount = 0)
|
||||
@ -1080,7 +1079,7 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function PosSetEx(const ASubStrSet, AString: string;
|
||||
function PosSetEx(const ASubStrSet, AString: string;
|
||||
const Offset: integer): integer;
|
||||
begin
|
||||
for Result := Offset to Length(AString) do
|
||||
@ -1309,7 +1308,7 @@ begin
|
||||
|
||||
if State = dsRun
|
||||
then GDBPause(True);
|
||||
if ASet then
|
||||
if ASet then
|
||||
begin
|
||||
S := EscapeGDBCommand(AVariable);
|
||||
ExecuteCommand('-gdb-set env %s', [S], [cfIgnoreState, cfExternal]);
|
||||
@ -1321,7 +1320,7 @@ end;
|
||||
|
||||
function TGDBMIDebugger.GDBEvaluate(const AExpression: String;
|
||||
var AResult: String): Boolean;
|
||||
|
||||
|
||||
function MakePrintable(const AString: String): String;
|
||||
var
|
||||
n: Integer;
|
||||
@ -1353,7 +1352,7 @@ function TGDBMIDebugger.GDBEvaluate(const AExpression: String;
|
||||
if InString
|
||||
then Result := Result + '''';
|
||||
end;
|
||||
|
||||
|
||||
var
|
||||
R: TGDBMIExecResult;
|
||||
S: String;
|
||||
@ -1541,7 +1540,7 @@ function TGDBMIDebugger.GDBStop: Boolean;
|
||||
begin
|
||||
if State = dsError
|
||||
then begin
|
||||
// We don't know the state of the debugger,
|
||||
// We don't know the state of the debugger,
|
||||
// force a reinit. Let's hope this works.
|
||||
DebugProcess.Terminate(0);
|
||||
Done;
|
||||
@ -1733,14 +1732,14 @@ begin
|
||||
idx := 8; // the char after ' times>'
|
||||
len := Length(S);
|
||||
if v <= 1 then Continue;
|
||||
|
||||
|
||||
// limit the amount of repeats
|
||||
if v > 1000
|
||||
then begin
|
||||
Trailor := Trailor + Format('###(repeat truncated: %u -> 1000)###', [v]);
|
||||
v := 1000;
|
||||
end;
|
||||
|
||||
|
||||
// make sure result has some room
|
||||
SetLength(Result, Length(Result) + v - 1);
|
||||
while v > 1 do begin
|
||||
@ -1817,10 +1816,10 @@ procedure TGDBMIDebugger.Init;
|
||||
FGDBVersion := '';
|
||||
FGDBOS := '';
|
||||
FGDBCPU := '';
|
||||
|
||||
|
||||
if not ExecuteCommand('-gdb-version', [], [cfNoMiCommand], R) // No MI since the output is no MI
|
||||
then Exit;
|
||||
|
||||
|
||||
S := GetPart(['configured as \"'], ['\"'], R.Values, False, False);
|
||||
if Pos('--target=', S) <> 0 then
|
||||
S := GetPart('--target=', '', S);
|
||||
@ -1830,11 +1829,11 @@ procedure TGDBMIDebugger.Init;
|
||||
|
||||
FGDBVersion := GetPart(['('], [')'], R.Values, False, False);
|
||||
if FGDBVersion <> '' then Exit;
|
||||
|
||||
|
||||
FGDBVersion := GetPart(['gdb '], [#10, #13], R.Values, True, False);
|
||||
if FGDBVersion <> '' then Exit;
|
||||
end;
|
||||
|
||||
|
||||
procedure CheckGDBVersion;
|
||||
begin
|
||||
if FGDBVersion < '5.3'
|
||||
@ -1851,20 +1850,20 @@ procedure TGDBMIDebugger.Init;
|
||||
begin
|
||||
FPauseWaitState := pwsNone;
|
||||
FInExecuteCount := 0;
|
||||
|
||||
|
||||
if CreateDebugProcess('-silent -i mi -nx')
|
||||
then begin
|
||||
if not ParseInitialization
|
||||
then begin
|
||||
SetState(dsError);
|
||||
Exit;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
|
||||
ExecuteCommand('-gdb-set confirm off', []);
|
||||
// for win32, turn off a new console otherwise breaking gdb will fail
|
||||
// ignore the error on other platforms
|
||||
ExecuteCommand('-gdb-set new-console off', [cfIgnoreError]);
|
||||
|
||||
|
||||
ParseGDBVersion;
|
||||
CheckGDBVersion;
|
||||
|
||||
@ -1887,12 +1886,12 @@ procedure TGDBMIDebugger.InterruptTarget;
|
||||
ThreadID: Cardinal;
|
||||
E: Integer;
|
||||
Emsg: PChar;
|
||||
begin
|
||||
begin
|
||||
Result := False;
|
||||
|
||||
|
||||
hProcess := OpenProcess(PROCESS_CREATE_THREAD or PROCESS_QUERY_INFORMATION or PROCESS_VM_OPERATION or PROCESS_VM_WRITE or PROCESS_VM_READ, False, TargetPID);
|
||||
if hProcess = 0 then Exit;
|
||||
|
||||
|
||||
try
|
||||
hThread := _CreateRemoteThread(hProcess, nil, 0, DebugBreakAddr, nil, 0, ThreadID);
|
||||
if hThread = 0
|
||||
@ -1925,9 +1924,9 @@ begin
|
||||
// GenerateConsoleCtrlEvent is nice, but only works if both gdb and
|
||||
// our target have a console. On win95 and family this is our only
|
||||
// option, on NT4+ we have a choice. Since this is not likely that
|
||||
// we have a console, we do it the hard way. On XP there exists
|
||||
// we have a console, we do it the hard way. On XP there exists
|
||||
// DebugBreakProcess, but it does efectively the same.
|
||||
|
||||
|
||||
if (DebugBreakAddr = nil)
|
||||
or not Assigned(_CreateRemoteThread)
|
||||
or not TryNT
|
||||
@ -1935,7 +1934,7 @@ begin
|
||||
// We have no other choice than trying this
|
||||
GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, TargetPID);
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
@ -1955,7 +1954,7 @@ begin
|
||||
|
||||
// we're stopped in our thread
|
||||
if FPauseWaitState = pwsInternal then Exit; // internal, dont care
|
||||
|
||||
|
||||
S := '';
|
||||
if not ExecuteCommand('-thread-list-ids', [cfIgnoreError], R) then Exit;
|
||||
List := TGDBMINameValueList.Create(R);
|
||||
@ -2019,12 +2018,12 @@ begin
|
||||
Location.SrcLine := StrToIntDef(Frame.Values['line'], -1);
|
||||
|
||||
Frame.Free;
|
||||
|
||||
|
||||
DoCurrent(Location);
|
||||
end;
|
||||
|
||||
function TGDBMIDebugger.ProcessResult(var AResult: TGDBMIExecResult): Boolean;
|
||||
|
||||
|
||||
function DoResultRecord(Line: String): Boolean;
|
||||
var
|
||||
ResultClass: String;
|
||||
@ -2063,7 +2062,7 @@ function TGDBMIDebugger.ProcessResult(var AResult: TGDBMIExecResult): Boolean;
|
||||
DebugLn('[WARNING] Debugger: Unknown result class: ', ResultClass);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure DoConsoleStream(Line: String);
|
||||
var
|
||||
len: Integer;
|
||||
@ -2090,7 +2089,7 @@ function TGDBMIDebugger.ProcessResult(var AResult: TGDBMIExecResult): Boolean;
|
||||
Line := Line + LineEnding;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
AResult.Values := AResult.Values + Line;
|
||||
end;
|
||||
end;
|
||||
@ -2256,7 +2255,7 @@ function TGDBMIDebugger.ProcessStopped(const AParams: String; const AIgnoreSigIn
|
||||
Result.SrcFile := GetPart('\"', '\"', R.Values);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
function GetExceptionInfo: TGDBMIExceptionInfo;
|
||||
begin
|
||||
if tfRTLUsesRegCall in FTargetFlags
|
||||
@ -2274,7 +2273,7 @@ function TGDBMIDebugger.ProcessStopped(const AParams: String; const AIgnoreSigIn
|
||||
procedure ProcessException(AInfo: TGDBMIExceptionInfo);
|
||||
var
|
||||
ExceptionMessage: String;
|
||||
begin
|
||||
begin
|
||||
if dfImplicidTypes in FDebuggerFlags
|
||||
then begin
|
||||
ExceptionMessage := GetText('^Exception(%s)^.FMessage', [AInfo.ObjAddr]);
|
||||
@ -2286,7 +2285,7 @@ function TGDBMIDebugger.ProcessStopped(const AParams: String; const AIgnoreSigIn
|
||||
DoException(AInfo.Name, ExceptionMessage);
|
||||
DoCurrent(GetLocation);
|
||||
end;
|
||||
|
||||
|
||||
procedure ProcessBreak;
|
||||
var
|
||||
ErrorNo: Integer;
|
||||
@ -2299,7 +2298,7 @@ function TGDBMIDebugger.ProcessStopped(const AParams: String; const AIgnoreSigIn
|
||||
DoException(Format('RunError(%d)', [ErrorNo]), '');
|
||||
DoCurrent(GetLocation);
|
||||
end;
|
||||
|
||||
|
||||
procedure ProcessRunError;
|
||||
var
|
||||
ErrorNo: Integer;
|
||||
@ -2329,10 +2328,10 @@ function TGDBMIDebugger.ProcessStopped(const AParams: String; const AIgnoreSigIn
|
||||
if not AIgnoreSigIntState
|
||||
or not SigInt
|
||||
then SetState(dsPause);
|
||||
|
||||
|
||||
if not SigInt
|
||||
then DoException('External: ' + S, '');
|
||||
|
||||
|
||||
if not AIgnoreSigIntState
|
||||
or not SigInt
|
||||
then ProcessFrame(AList.Values['frame']);
|
||||
@ -2348,7 +2347,7 @@ var
|
||||
begin
|
||||
Result := True;
|
||||
FCurrentStackFrame := 0;
|
||||
|
||||
|
||||
List := TGDBMINameValueList.Create(AParams);
|
||||
try
|
||||
Reason := List.Values['reason'];
|
||||
@ -2357,14 +2356,14 @@ begin
|
||||
SetState(dsStop);
|
||||
Exit;
|
||||
end;
|
||||
|
||||
|
||||
if Reason = 'exited'
|
||||
then begin
|
||||
SetExitCode(StrToIntDef(List.Values['exit-code'], 0));
|
||||
SetState(dsStop);
|
||||
Exit;
|
||||
end;
|
||||
|
||||
|
||||
if Reason = 'exited-signalled'
|
||||
then begin
|
||||
SetState(dsStop);
|
||||
@ -2372,13 +2371,13 @@ begin
|
||||
// ProcessFrame(List.Values['frame']);
|
||||
Exit;
|
||||
end;
|
||||
|
||||
|
||||
if Reason = 'signal-received'
|
||||
then begin
|
||||
ProcessSignalReceived(List);
|
||||
Exit;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
if Reason = 'breakpoint-hit'
|
||||
then begin
|
||||
BreakID := StrToIntDef(List.Values['bkptno'], -1);
|
||||
@ -2402,7 +2401,7 @@ begin
|
||||
ProcessRunError;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
|
||||
if BreakID = FExceptionBreakID
|
||||
then begin
|
||||
ExceptionInfo := GetExceptionInfo;
|
||||
@ -2416,7 +2415,7 @@ begin
|
||||
end;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
|
||||
BreakPoint := TGDBMIBreakPoint(FindBreakpoint(BreakID));
|
||||
if BreakPoint <> nil
|
||||
then begin
|
||||
@ -2433,33 +2432,33 @@ begin
|
||||
end;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
|
||||
if Reason = 'function-finished'
|
||||
then begin
|
||||
SetState(dsPause);
|
||||
ProcessFrame(List.Values['frame']);
|
||||
Exit;
|
||||
end;
|
||||
|
||||
|
||||
if Reason = 'end-stepping-range'
|
||||
then begin
|
||||
SetState(dsPause);
|
||||
ProcessFrame(List.Values['frame']);
|
||||
Exit;
|
||||
end;
|
||||
|
||||
|
||||
if Reason = 'location-reached'
|
||||
then begin
|
||||
SetState(dsPause);
|
||||
ProcessFrame(List.Values['frame']);
|
||||
Exit;
|
||||
end;
|
||||
|
||||
|
||||
Result := False;
|
||||
DebugLn('[WARNING] Debugger: Unknown stopped reason: ', Reason);
|
||||
finally
|
||||
List.Free;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TGDBMIDebugger.RequestCommand(const ACommand: TDBGCommand; const AParams: array of const): Boolean;
|
||||
@ -2522,7 +2521,7 @@ function TGDBMIDebugger.StartDebugging(const AContinueCommand: String): Boolean;
|
||||
|
||||
ExecuteCommand('-data-evaluate-expression FPC_THREADVAR_RELOCATE_PROC', [cfIgnoreError], R);
|
||||
if R.State <> dsError then Exit; // guessed right
|
||||
|
||||
|
||||
// next attempt, posibly no symbols, try functions
|
||||
if CheckFunction('FPC_CPUINIT') then Exit; // function present --> not 1.0
|
||||
|
||||
@ -2536,7 +2535,7 @@ function TGDBMIDebugger.StartDebugging(const AContinueCommand: String): Boolean;
|
||||
// params are passes by stack
|
||||
Exclude(FTargetFlags, tfRTLUsesRegCall);
|
||||
end;
|
||||
|
||||
|
||||
function InsertBreakPoint(const AName: String): Integer;
|
||||
var
|
||||
R: TGDBMIExecResult;
|
||||
@ -2555,7 +2554,7 @@ function TGDBMIDebugger.StartDebugging(const AContinueCommand: String): Boolean;
|
||||
// assume some defaults
|
||||
FTargetPtrSize := 4;
|
||||
FTargetIsBE := False;
|
||||
|
||||
|
||||
case StringCase(AFileType, [
|
||||
'efi-app-ia32', 'elf32-i386', 'pei-i386',
|
||||
'elf64-x86-64',
|
||||
@ -2643,7 +2642,7 @@ function TGDBMIDebugger.StartDebugging(const AContinueCommand: String): Boolean;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
|
||||
function SetTempMainBreak: Boolean;
|
||||
var
|
||||
R: TGDBMIExecResult;
|
||||
@ -2672,7 +2671,7 @@ function TGDBMIDebugger.StartDebugging(const AContinueCommand: String): Boolean;
|
||||
FMainAddr := StrToIntDef(ResultList.Values['addr'], 0);
|
||||
ResultList.Free;
|
||||
end;
|
||||
|
||||
|
||||
var
|
||||
R: TGDBMIExecResult;
|
||||
FileType, EntryPoint: String;
|
||||
@ -2705,7 +2704,7 @@ begin
|
||||
// also call execute -exec-arguments if there are no arguments in this run
|
||||
// so the possible arguments of a previous run are cleared
|
||||
ExecuteCommand('-exec-arguments %s', [Arguments], [cfIgnoreError]);
|
||||
|
||||
|
||||
if tfHasSymbols in FTargetFlags
|
||||
then begin
|
||||
// Make sure we are talking pascal
|
||||
@ -2716,7 +2715,7 @@ begin
|
||||
DebugLn('TGDBMIDebugger.StartDebugging Note: Target has no symbols');
|
||||
TempInstalled := False;
|
||||
end;
|
||||
|
||||
|
||||
// try Insert Break breakpoint
|
||||
// we might have rtl symbols
|
||||
if FExceptionBreakID = -1
|
||||
@ -2751,7 +2750,7 @@ begin
|
||||
end;
|
||||
|
||||
SetTargetInfo(FileType);
|
||||
|
||||
|
||||
if not TempInstalled and (EntryPoint <> '')
|
||||
then begin
|
||||
// We could not set our initial break to get info and allow stepping
|
||||
@ -2760,9 +2759,9 @@ begin
|
||||
ExecuteCommand('-break-insert -t *%u', [FMainAddr], [cfIgnoreError], R);
|
||||
TempInstalled := R.State <> dsError;
|
||||
end;
|
||||
|
||||
|
||||
FTargetPID := 0;
|
||||
|
||||
|
||||
// fire the first step
|
||||
if TempInstalled
|
||||
and ExecuteCommand('-exec-run', [], R)
|
||||
@ -2807,7 +2806,7 @@ begin
|
||||
else SetState(dsPause);
|
||||
end
|
||||
else SetState(R.State);
|
||||
|
||||
|
||||
if State = dsPause
|
||||
then ProcessFrame;
|
||||
|
||||
@ -2850,7 +2849,7 @@ end;
|
||||
procedure TGDBMIBreakPoint.DoStateChange(const AOldState: TDBGState);
|
||||
begin
|
||||
inherited DoStateChange(AOldState);
|
||||
|
||||
|
||||
case Debugger.State of
|
||||
dsInit: begin
|
||||
SetBreakpoint;
|
||||
@ -2862,11 +2861,6 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TGDBMIBreakPoint.Hit(var ACanContinue: Boolean);
|
||||
begin
|
||||
DoHit(HitCount + 1, ACanContinue);
|
||||
end;
|
||||
|
||||
procedure TGDBMIBreakPoint.SetBreakpoint;
|
||||
begin
|
||||
if Debugger = nil then Exit;
|
||||
@ -2878,7 +2872,7 @@ begin
|
||||
then TGDBMIDebugger(Debugger).GDBPause(True);
|
||||
TGDBMIDebugger(Debugger).ExecuteCommand('-break-insert %s:%d',
|
||||
[ExtractFileName(Source), Line], [cfIgnoreError], @SetBreakPointCallback, 0);
|
||||
|
||||
|
||||
end;
|
||||
|
||||
procedure TGDBMIBreakPoint.SetBreakPointCallback(const AResult: TGDBMIExecResult; const ATag: Integer);
|
||||
@ -2895,7 +2889,7 @@ begin
|
||||
else SetValid(vsInvalid);
|
||||
UpdateExpression;
|
||||
UpdateEnable;
|
||||
|
||||
|
||||
if (FBreakID <> 0)
|
||||
and Enabled
|
||||
and (TGDBMIDebugger(Debugger).FBreakAtMain = nil)
|
||||
@ -2915,7 +2909,7 @@ procedure TGDBMIBreakPoint.ReleaseBreakPoint;
|
||||
begin
|
||||
if FBreakID = 0 then Exit;
|
||||
if Debugger = nil then Exit;
|
||||
|
||||
|
||||
if Debugger.State = dsRun
|
||||
then TGDBMIDebugger(Debugger).GDBPause(True);
|
||||
TGDBMIDebugger(Debugger).ExecuteCommand('-break-delete %d', [FBreakID], []);
|
||||
@ -2933,7 +2927,7 @@ begin
|
||||
end;
|
||||
|
||||
procedure TGDBMIBreakPoint.UpdateEnable;
|
||||
const
|
||||
const
|
||||
// Use shortstring as fix for fpc 1.9.5 [2004/07/15]
|
||||
CMD: array[Boolean] of ShortString = ('disable', 'enable');
|
||||
begin
|
||||
@ -3439,7 +3433,7 @@ begin
|
||||
end;
|
||||
|
||||
function TGDBMICallStack.CreateStackEntry(AIndex: Integer): TCallStackEntry;
|
||||
var
|
||||
var
|
||||
R: TGDBMIExecResult;
|
||||
ArgList, FrameList: TGDBMINameValueList;
|
||||
begin
|
||||
@ -3453,7 +3447,7 @@ begin
|
||||
then ArgList := TGDBMINameValueList.Create(R, ['stack-args', 'frame', 'args'])
|
||||
else ArgList := nil;
|
||||
|
||||
|
||||
|
||||
TGDBMIDebugger(Debugger).ExecuteCommand('-stack-list-frames %0:d %0:d',
|
||||
[AIndex], [cfIgnoreError], R);
|
||||
|
||||
@ -3767,9 +3761,9 @@ var
|
||||
S: String;
|
||||
List: TGDBMINameValueList;
|
||||
GDBType: TGDBType;
|
||||
begin
|
||||
begin
|
||||
Result := False;
|
||||
|
||||
|
||||
if FLeft = nil
|
||||
then AResult := ''
|
||||
else begin
|
||||
@ -3783,7 +3777,7 @@ begin
|
||||
AResult := AResult + '(' + S + ')';
|
||||
end
|
||||
else if FOperator = '['
|
||||
then begin
|
||||
then begin
|
||||
if not FRight.GetExpression(S) then Exit;
|
||||
AResult := AResult + '[' + S + ']';
|
||||
end
|
||||
@ -3791,7 +3785,7 @@ begin
|
||||
if (Length(FOperator) > 0)
|
||||
and (FOperator[1] = '''')
|
||||
then AResult := AResult + ConvertToCString(FOperator)
|
||||
else begin
|
||||
else begin
|
||||
GDBType := FDebugger.GetGDBTypeInfo(FOperator);
|
||||
if GDBType = nil
|
||||
then begin
|
||||
@ -3801,7 +3795,7 @@ begin
|
||||
|
||||
if not FDebugger.ExecuteCommand('ptype %s', [FOperator], [cfIgnoreError, cfNoMiCommand], R)
|
||||
then Exit;
|
||||
|
||||
|
||||
if R.State = dsError
|
||||
then begin
|
||||
// no type possible, use literal operator
|
||||
@ -3829,7 +3823,7 @@ begin
|
||||
AResult := AResult + S;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
@ -3843,5 +3837,5 @@ end;
|
||||
|
||||
initialization
|
||||
RegisterDebugger(TGDBMIDebugger);
|
||||
|
||||
|
||||
end.
|
||||
|
@ -62,6 +62,7 @@ type
|
||||
FExceptions: TIDEExceptions;
|
||||
FSignals: TIDESignals;
|
||||
FBreakPoints: TIDEBreakPoints;
|
||||
FBreakPointGroups: TIDEBreakPointGroups;
|
||||
FLocals: TIDELocals;
|
||||
FWatches: TIDEWatches;
|
||||
FRegisters: TIDERegisters;
|
||||
@ -120,6 +121,7 @@ type
|
||||
property State: TDBGState read GetState; // The current state of the debugger
|
||||
|
||||
property BreakPoints: TIDEBreakPoints read FBreakpoints; // A list of breakpoints for the current project
|
||||
property BreakPointGroups: TIDEBreakPointGroups read FBreakPointGroups;
|
||||
property Exceptions: TIDEExceptions read FExceptions; // A list of exceptions we should ignore
|
||||
property CallStack: TIDECallStack read FCallStack;
|
||||
property Locals: TIDELocals read FLocals;
|
||||
|
@ -40,19 +40,19 @@ uses
|
||||
{$IFDEF IDE_MEM_CHECK}
|
||||
MemCheck,
|
||||
{$ENDIF}
|
||||
Classes, SysUtils, Forms, Controls, Dialogs, Menus, FileUtil, LCLProc,
|
||||
Classes, SysUtils, Forms, Controls, Dialogs, Menus, ExtCtrls, FileUtil, LCLProc,
|
||||
Laz_XMLCfg,
|
||||
{ for Get/SetForegroundWindow }
|
||||
LCLType, LCLIntf,
|
||||
SynEdit, CodeCache, CodeToolManager,
|
||||
MenuIntf, IDECommands, LazIDEIntf, ProjectIntf,
|
||||
LazConf,
|
||||
LazConf,
|
||||
CompilerOptions, EditorOptions, EnvironmentOpts, ProjectOpts, KeyMapping, SourceEditor,
|
||||
ProjectDefs, Project, IDEProcs, InputHistory, Debugger,
|
||||
ProjectDefs, Project, IDEProcs, InputHistory, Debugger, CmdLineDebugger,
|
||||
IDEOptionDefs, LazarusIDEStrConsts,
|
||||
MainBar, MainIntf, MainBase, BaseBuildManager,
|
||||
SourceMarks,
|
||||
DebuggerDlg, Watchesdlg, BreakPointsdlg, LocalsDlg, WatchPropertyDlg,
|
||||
DebuggerDlg, Watchesdlg, BreakPointsdlg, BreakPropertyDlg, LocalsDlg, WatchPropertyDlg,
|
||||
CallStackDlg, EvaluateDlg, RegistersDlg, AssemblerDlg, DBGOutputForm,
|
||||
GDBMIDebugger, SSHGDBMIDebugger, ProcessDebugger,
|
||||
BaseDebugManager;
|
||||
@ -73,6 +73,7 @@ type
|
||||
{ TDebugManager }
|
||||
|
||||
TDebugManager = class(TBaseDebugManager)
|
||||
procedure BreakAutoContinueTimer(Sender: TObject);
|
||||
// Menu events
|
||||
procedure mnuViewDebugDialogClick(Sender: TObject);
|
||||
procedure mnuResetDebuggerClicked(Sender: TObject);
|
||||
@ -81,6 +82,7 @@ type
|
||||
function OnSrcNotebookAddWatchesAtCursor(Sender: TObject): boolean;
|
||||
|
||||
// Debugger events
|
||||
procedure DebuggerBreakPointHit(ADebugger: TDebugger; ABreakPoint: TBaseBreakPoint; var ACanContinue: Boolean);
|
||||
procedure DebuggerChangeState(ADebugger: TDebugger; OldState: TDBGState);
|
||||
procedure DebuggerCurrentLine(Sender: TObject; const ALocation: TDBGLocationRec);
|
||||
procedure DebuggerOutput(Sender: TObject; const AText: String);
|
||||
@ -90,11 +92,13 @@ type
|
||||
procedure DebugDialogDestroy(Sender: TObject);
|
||||
private
|
||||
FDebugger: TDebugger;
|
||||
FBreakPointGroups: TIDEBreakPointGroups;
|
||||
FDialogs: array[TDebugDialogType] of TDebuggerDlg;
|
||||
FPrevShownWindow: HWND;
|
||||
// keep track of the last reported location
|
||||
FCurrentLocation: TDBGLocationRec;
|
||||
// last hit breakpoint
|
||||
FCurrentBreakpoint: TIDEBreakpoint;
|
||||
FAutoContinueTimer: TTimer;
|
||||
|
||||
// When a source file is not found, the user can choose one
|
||||
// here are all choices stored
|
||||
@ -946,7 +950,7 @@ begin
|
||||
else
|
||||
AddMenuItem('Enable Breakpoint',true,@OnToggleEnableMenuItemClick);
|
||||
AddMenuItem('Delete Breakpoint',true,@OnDeleteMenuItemClick);
|
||||
AddMenuItem('View Breakpoint Properties',false,@OnViewPropertiesMenuItemClick);
|
||||
AddMenuItem('View Breakpoint Properties',true,@OnViewPropertiesMenuItemClick);
|
||||
// add separator
|
||||
AddMenuItem('-',true,nil);
|
||||
end;
|
||||
@ -1176,6 +1180,23 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TDebugManager.BreakAutoContinueTimer(Sender: TObject);
|
||||
begin
|
||||
FAutoContinueTimer.Enabled := False;
|
||||
FDebugger.Run;
|
||||
end;
|
||||
|
||||
procedure TDebugManager.DebuggerBreakPointHit(ADebugger: TDebugger;
|
||||
ABreakPoint: TBaseBreakPoint; var ACanContinue: Boolean);
|
||||
begin
|
||||
FCurrentBreakPoint := nil;
|
||||
if FBreakPoints = nil then Exit;
|
||||
if ABreakpoint = nil then Exit;
|
||||
if ACanContinue then Exit;
|
||||
|
||||
FCurrentBreakPoint := FBreakPoints.Find(ABreakPoint.Source, ABreakPoint.SourceLine);
|
||||
end;
|
||||
|
||||
procedure TDebugManager.mnuViewDebugDialogClick(Sender: TObject);
|
||||
begin
|
||||
ViewDebugDialog(TDebugDialogType((Sender as TIDEMenuItem).Tag));
|
||||
@ -1286,20 +1307,27 @@ begin
|
||||
if MainIDE.ToolStatus in [itNone,itDebugger]
|
||||
then MainIDE.ToolStatus := TOOLSTATEMAP[FDebugger.State];
|
||||
|
||||
FAutoContinueTimer.Enabled := false;
|
||||
if (FDebugger.State in [dsRun])
|
||||
then begin
|
||||
// hide IDE during run
|
||||
if EnvironmentOptions.HideIDEOnRun
|
||||
and (MainIDE.ToolStatus=itDebugger) then
|
||||
MainIDE.HideIDE;
|
||||
if EnvironmentOptions.HideIDEOnRun and (MainIDE.ToolStatus=itDebugger)
|
||||
then MainIDE.HideIDE;
|
||||
|
||||
if FPrevShownWindow <> 0 then
|
||||
begin
|
||||
SetForegroundWindow(FPrevShownWindow);
|
||||
FPrevShownWindow := 0;
|
||||
end;
|
||||
FCurrentBreakPoint := nil;
|
||||
end
|
||||
else begin
|
||||
if (OldState in [dsRun]) then
|
||||
if (FCurrentBreakPoint <> nil) and (FCurrentBreakPoint.AutoContinueTime > 0) then
|
||||
begin
|
||||
FAutoContinueTimer.Enabled := True;
|
||||
FAutoContinueTimer.Interval := FCurrentBreakPoint.AutoContinueTime;
|
||||
end
|
||||
else if (OldState in [dsRun]) then
|
||||
begin
|
||||
MainIDE.UnhideIDE;
|
||||
FPrevShownWindow := GetForegroundWindow;
|
||||
@ -1308,8 +1336,7 @@ begin
|
||||
end;
|
||||
|
||||
// unmark execution line
|
||||
if (FDebugger.State <> dsPause)
|
||||
and (SourceNotebook <> nil)
|
||||
if (FDebugger.State <> dsPause) and (SourceNotebook <> nil)
|
||||
then begin
|
||||
Editor := SourceNotebook.GetActiveSE;
|
||||
if Editor <> nil
|
||||
@ -1329,10 +1356,10 @@ begin
|
||||
dsStop: begin
|
||||
if (OldState<>dsIdle)
|
||||
then begin
|
||||
if EnvironmentOptions.DebuggerShowStopMessage then begin
|
||||
MessageDlg(lisExecutionStopped,
|
||||
Format(lisExecutionStoppedOn, [#13#13]),
|
||||
mtInformation, [mbOK],0);
|
||||
if EnvironmentOptions.DebuggerShowStopMessage
|
||||
then begin
|
||||
MessageDlg(lisExecutionStopped,
|
||||
Format(lisExecutionStoppedOn, [#13#13]), mtInformation, [mbOK],0);
|
||||
end;
|
||||
FDebugger.FileName := '';
|
||||
|
||||
@ -1355,6 +1382,7 @@ var
|
||||
SrcLine: Integer;
|
||||
i: Integer;
|
||||
StackEntry: TCallStackEntry;
|
||||
FocusEditor: Boolean;
|
||||
begin
|
||||
if (Sender<>FDebugger) or (Sender=nil) then exit;
|
||||
if Destroying then exit;
|
||||
@ -1417,9 +1445,9 @@ begin
|
||||
SourceNotebook.ClearExecutionLines;
|
||||
SourceNotebook.ClearErrorLines;
|
||||
end;
|
||||
|
||||
// jump editor to execution line
|
||||
if MainIDE.DoJumpToCodePos(nil,nil,NewSource,1,SrcLine,-1,true)<>mrOk
|
||||
FocusEditor := (FCurrentBreakPoint = nil) or (FCurrentBreakPoint.AutoContinueTime = 0);
|
||||
if MainIDE.DoJumpToCodePos(nil,nil,NewSource,1,SrcLine,-1,true, FocusEditor)<>mrOk
|
||||
then exit;
|
||||
|
||||
// mark execution line
|
||||
@ -1596,6 +1624,10 @@ begin
|
||||
|
||||
FUserSourceFiles := TStringList.Create;
|
||||
|
||||
FAutoContinueTimer := TTimer.Create(Self);
|
||||
FAutoContinueTimer.Enabled := False;
|
||||
FAutoContinueTimer.OnTimer := @BreakAutoContinueTimer;
|
||||
|
||||
inherited Create(TheOwner);
|
||||
end;
|
||||
|
||||
@ -1603,7 +1635,9 @@ destructor TDebugManager.Destroy;
|
||||
var
|
||||
DialogType: TDebugDialogType;
|
||||
begin
|
||||
FDestroying:=true;
|
||||
FDestroying := true;
|
||||
|
||||
FreeAndNil(FAutoContinueTimer);
|
||||
|
||||
for DialogType := Low(TDebugDialogType) to High(TDebugDialogType) do
|
||||
DestroyDebugDialog(DialogType);
|
||||
@ -1945,10 +1979,11 @@ begin
|
||||
|
||||
ClearDebugOutputLog;
|
||||
|
||||
FDebugger.OnState := @DebuggerChangeState;
|
||||
FDebugger.OnCurrent := @DebuggerCurrentLine;
|
||||
FDebugger.OnDbgOutput := @DebuggerOutput;
|
||||
FDebugger.OnException := @DebuggerException;
|
||||
FDebugger.OnBreakPointHit := @DebuggerBreakPointHit;
|
||||
FDebugger.OnState := @DebuggerChangeState;
|
||||
FDebugger.OnCurrent := @DebuggerCurrentLine;
|
||||
FDebugger.OnDbgOutput := @DebuggerOutput;
|
||||
FDebugger.OnException := @DebuggerException;
|
||||
|
||||
if FDebugger.State = dsNone
|
||||
then begin
|
||||
@ -2246,17 +2281,12 @@ end;
|
||||
|
||||
function TDebugManager.ShowBreakPointProperties(const ABreakpoint: TIDEBreakPoint): TModalresult;
|
||||
begin
|
||||
Result:=mrCancel;
|
||||
// ToDo
|
||||
Result := TBreakPropertyDlg.Create(Self, ABreakpoint).ShowModal;
|
||||
end;
|
||||
|
||||
function TDebugManager.ShowWatchProperties(const AWatch: TIDEWatch): TModalresult;
|
||||
begin
|
||||
with TWatchPropertyDlg.Create(Self, AWatch) do
|
||||
begin
|
||||
Result := ShowModal;
|
||||
Free;
|
||||
end;
|
||||
Result := TWatchPropertyDlg.Create(Self, AWatch).ShowModal;
|
||||
end;
|
||||
|
||||
procedure TDebugManager.SetDebugger(const ADebugger: TDebugger);
|
||||
@ -2286,3 +2316,4 @@ end;
|
||||
|
||||
end.
|
||||
|
||||
|
||||
|
@ -3850,6 +3850,7 @@ resourcestring
|
||||
lisBreak = 'Break';
|
||||
lisEnableGroup = 'Enable Group';
|
||||
lisDisableGroup = 'Disable Group';
|
||||
lisAutoContinue = 'Auto Continue';
|
||||
lisDisabled = 'Disabled';
|
||||
lisInvalidOff = 'Invalid (Off)';
|
||||
lisInvalidOn = 'Invalid (On)';
|
||||
|
13
ide/main.pp
13
ide/main.pp
@ -849,7 +849,7 @@ type
|
||||
ActiveSrcEdit: TSourceEditor;
|
||||
ActiveUnitInfo: TUnitInfo;
|
||||
NewSource: TCodeBuffer; NewX, NewY, NewTopLine: integer;
|
||||
AddJumpPoint: boolean): TModalResult; override;
|
||||
AddJumpPoint: boolean; FocusEditor: Boolean=True): TModalResult; override;
|
||||
procedure DoJumpToCodeToolBossError; override;
|
||||
procedure UpdateSourceNames;
|
||||
procedure SaveSourceEditorChangesToCodeCache(PageIndex: integer); override;
|
||||
@ -10770,6 +10770,7 @@ procedure TMainIDE.UpdateCaption;
|
||||
var NewCaption: string;
|
||||
begin
|
||||
if MainIDEBar=nil then exit;
|
||||
if ToolStatus = itExiting then exit;
|
||||
NewCaption := Format(lisLazarusEditorV, [GetLazarusVersionString]);
|
||||
if MainBarSubTitle<>'' then begin
|
||||
NewCaption:=NewCaption+' - '+MainBarSubTitle;
|
||||
@ -12185,7 +12186,7 @@ end;
|
||||
function TMainIDE.DoJumpToCodePos(
|
||||
ActiveSrcEdit: TSourceEditor; ActiveUnitInfo: TUnitInfo;
|
||||
NewSource: TCodeBuffer; NewX, NewY, NewTopLine: integer;
|
||||
AddJumpPoint: boolean): TModalResult;
|
||||
AddJumpPoint: boolean; FocusEditor: boolean): TModalResult;
|
||||
var
|
||||
NewSrcEdit: TSourceEditor;
|
||||
NewUnitInfo: TUnitInfo;
|
||||
@ -12235,8 +12236,12 @@ begin
|
||||
//DebugLn('TMainIDE.DoJumpToCodePos NewY=',dbgs(NewY),' ',dbgs(TopLine),' ',dbgs(NewTopLine));
|
||||
LeftChar:=Max(NewX-CharsInWindow,1);
|
||||
end;
|
||||
SourceNoteBook.ShowOnTop;
|
||||
SourceNotebook.FocusEditor;
|
||||
|
||||
if FocusEditor
|
||||
then begin
|
||||
SourceNoteBook.ShowOnTop;
|
||||
SourceNotebook.FocusEditor;
|
||||
end;
|
||||
UpdateSourceNames;
|
||||
Result:=mrOk;
|
||||
end;
|
||||
|
@ -5,7 +5,7 @@
|
||||
----------------------------------------
|
||||
TMainIDEBase is the ancestor of TMainIDE. The various top level parts of the
|
||||
IDE (called bosses/managers) access the TMainIDE via TMainIDEBase.
|
||||
|
||||
|
||||
|
||||
main.pp - TMainIDE = class(TMainIDEBase)
|
||||
The highest manager/boss of the IDE. Only lazarus.pp uses
|
||||
@ -115,7 +115,7 @@ type
|
||||
procedure mnuWindowItemClick(Sender: TObject); virtual;
|
||||
procedure mnuWindowSourceItemClick(Sender: TObject); virtual;
|
||||
procedure OnMainBarDestroy(Sender: TObject); virtual;
|
||||
|
||||
|
||||
procedure ConnectOutputFilter;
|
||||
|
||||
public
|
||||
@ -165,15 +165,15 @@ type
|
||||
ActiveSrcEdit: TSourceEditor;
|
||||
ActiveUnitInfo: TUnitInfo;
|
||||
NewSource: TCodeBuffer; NewX, NewY, NewTopLine: integer;
|
||||
AddJumpPoint: boolean): TModalResult; virtual; abstract;
|
||||
|
||||
AddJumpPoint: boolean; FocusEditor: Boolean=True): TModalResult; virtual; abstract;
|
||||
|
||||
procedure FindInFilesPerDialog(AProject: TProject); override;
|
||||
procedure FindInFiles(AProject: TProject; const FindText: string); override;
|
||||
end;
|
||||
|
||||
var
|
||||
MainIDE: TMainIDEBase = nil;
|
||||
|
||||
|
||||
{ Normally the IDE builds itself with packages named in config files.
|
||||
When the IDE should keep the packages installed in the current executable
|
||||
set KeepInstalledPackages to true. }
|
||||
@ -1018,10 +1018,10 @@ begin
|
||||
if (AForm.Designer<>nil) and (WindowsList.IndexOf(AForm)<0) then
|
||||
WindowsList.Add(AForm);
|
||||
end;
|
||||
|
||||
|
||||
// create menuitems
|
||||
ItemCount := WindowsList.Count;
|
||||
for i:=0 to WindowsList.Count-1 do
|
||||
for i:=0 to WindowsList.Count-1 do
|
||||
begin
|
||||
CurMenuItem := GetMenuItem(i);
|
||||
CurMenuItem.Caption:=TCustomForm(WindowsList[i]).Caption;
|
||||
@ -1031,14 +1031,14 @@ begin
|
||||
|
||||
//create source page menuitems
|
||||
|
||||
if (SourceNotebook<>nil) and (SourceNotebook.Notebook<>nil) and not (nbcPageListPopup in SourceNotebook.Notebook.GetCapabilities) then
|
||||
if (SourceNotebook<>nil) and (SourceNotebook.Notebook<>nil) and not (nbcPageListPopup in SourceNotebook.Notebook.GetCapabilities) then
|
||||
begin
|
||||
CurMenuItem := GetMenuItem(ItemCount);
|
||||
CurMenuItem.OnClick:=nil;
|
||||
CurMenuItem.Caption:='-';
|
||||
inc(ItemCount);
|
||||
|
||||
for i := 0 to SourceNotebook.EditorCount-1 do
|
||||
for i := 0 to SourceNotebook.EditorCount-1 do
|
||||
begin
|
||||
CurMenuItem := GetMenuItem(ItemCount);
|
||||
CurMenuItem.Caption:=SourceNotebook.Editors[i].PageName;
|
||||
|
Loading…
Reference in New Issue
Block a user