#97, start asm view

This commit is contained in:
Basile Burg 2016-11-27 14:43:57 +01:00
parent 2f0655da97
commit 609303c983
No known key found for this signature in database
GPG Key ID: 1868039F415CB8CF
2 changed files with 251 additions and 123 deletions

View File

@ -1,9 +1,8 @@
inherited CEGdbWidget: TCEGdbWidget inherited CEGdbWidget: TCEGdbWidget
Left = 640 Left = 635
Height = 668 Height = 668
Top = 213 Top = 212
Width = 517 Width = 517
ActiveControl = Back
Caption = 'GDB commander' Caption = 'GDB commander'
ClientHeight = 668 ClientHeight = 668
ClientWidth = 517 ClientWidth = 517
@ -20,27 +19,27 @@ inherited CEGdbWidget: TCEGdbWidget
ClientWidth = 517 ClientWidth = 517
object Panel1: TPanel[0] object Panel1: TPanel[0]
Left = 0 Left = 0
Height = 394 Height = 385
Top = 196 Top = 205
Width = 517 Width = 517
Align = alClient Align = alClient
BevelOuter = bvNone BevelOuter = bvNone
ClientHeight = 394 ClientHeight = 385
ClientWidth = 517 ClientWidth = 517
TabOrder = 0 TabOrder = 0
object GroupBox3: TGroupBox object GroupBox3: TGroupBox
Left = 0 Left = 0
Height = 197 Height = 179
Top = 197 Top = 206
Width = 517 Width = 517
Align = alClient Align = alClient
Caption = 'CPU' Caption = 'CPU'
ClientHeight = 167 ClientHeight = 149
ClientWidth = 513 ClientWidth = 513
TabOrder = 0 TabOrder = 0
object cpuVIewer: TTIPropertyGrid object cpuVIewer: TTIPropertyGrid
Left = 0 Left = 0
Height = 167 Height = 149
Hint = 'cpu registers' Hint = 'cpu registers'
Top = 0 Top = 0
Width = 513 Width = 513
@ -55,67 +54,103 @@ inherited CEGdbWidget: TCEGdbWidget
ValueFont.Color = clMaroon ValueFont.Color = clMaroon
end end
end end
object GroupBox2: TGroupBox
Left = 0
Height = 191
Top = 0
Width = 517
Align = alTop
Caption = 'Variables'
ClientHeight = 161
ClientWidth = 513
TabOrder = 1
object varList: TListView
Left = 2
Height = 135
Top = 24
Width = 509
Align = alClient
BorderSpacing.Around = 2
Columns = <
item
AutoSize = True
Caption = 'Name'
Width = 47
end
item
AutoSize = True
Caption = 'Value'
Width = 458
end>
GridLines = True
HideSelection = False
ReadOnly = True
ScrollBars = ssAutoBoth
SortColumn = 0
SortType = stText
TabOrder = 0
ViewStyle = vsReport
end
object varListFlt: TListViewFilterEdit
Left = 2
Height = 20
Hint = 'locate variables'
Top = 2
Width = 509
ButtonWidth = 24
NumGlyphs = 1
Align = alTop
BorderSpacing.Around = 2
MaxLength = 0
TabOrder = 1
OnChange = varListFltChange
end
end
object Splitter4: TSplitter object Splitter4: TSplitter
Cursor = crVSplit Cursor = crVSplit
Left = 0 Left = 0
Height = 6 Height = 6
Top = 191 Top = 0
Width = 517 Width = 517
Align = alTop Align = alTop
ResizeAnchor = akTop ResizeAnchor = akTop
end end
object PageControl2: TPageControl
Left = 0
Height = 200
Top = 6
Width = 517
ActivePage = TabSheet4
Align = alTop
TabIndex = 1
TabOrder = 2
object TabSheet3: TTabSheet
Caption = 'Variables'
ClientHeight = 164
ClientWidth = 509
object varList: TListView
Left = 2
Height = 138
Top = 24
Width = 505
Align = alClient
BorderSpacing.Around = 2
Columns = <
item
AutoSize = True
Caption = 'Name'
Width = 47
end
item
AutoSize = True
Caption = 'Value'
Width = 454
end>
GridLines = True
HideSelection = False
ReadOnly = True
ScrollBars = ssAutoBoth
SortColumn = 0
SortType = stText
TabOrder = 0
ViewStyle = vsReport
end
object varListFlt: TListViewFilterEdit
Left = 2
Height = 20
Hint = 'locate variables'
Top = 2
Width = 505
ButtonWidth = 24
NumGlyphs = 1
Align = alTop
BorderSpacing.Around = 2
MaxLength = 0
TabOrder = 1
OnChange = varListFltChange
end
end
object TabSheet4: TTabSheet
Caption = 'Assembly'
ClientHeight = 164
ClientWidth = 509
object asmList: TListView
Left = 2
Height = 160
Top = 2
Width = 505
Align = alClient
AutoSort = False
BorderSpacing.Around = 2
Columns = <
item
AutoSize = True
Caption = 'Address'
Width = 60
end
item
AutoSize = True
Caption = 'Instruction'
Width = 441
end>
GridLines = True
HideSelection = False
ReadOnly = True
ScrollBars = ssAutoBoth
SortColumn = 0
TabOrder = 0
ViewStyle = vsReport
end
end
end
end end
object Panel3: TPanel[1] object Panel3: TPanel[1]
Left = 4 Left = 4
@ -152,55 +187,62 @@ inherited CEGdbWidget: TCEGdbWidget
TabOrder = 0 TabOrder = 0
end end
end end
object GroupBox1: TGroupBox[2] object Splitter3: TSplitter[2]
Left = 0
Height = 191
Top = 0
Width = 517
Align = alTop
Caption = 'Call stack'
ClientHeight = 161
ClientWidth = 513
TabOrder = 2
object lstCallStack: TListView
Left = 0
Height = 161
Hint = 'call stack'
Top = 0
Width = 513
Align = alClient
Columns = <
item
AutoSize = True
Caption = 'function'
Width = 62
end
item
AutoSize = True
Caption = 'address'
Width = 59
end
item
AutoSize = True
Caption = 'filename'
Width = 371
end>
GridLines = True
ReadOnly = True
TabOrder = 0
ViewStyle = vsReport
OnDblClick = lstCallStackDblClick
end
end
object Splitter3: TSplitter[3]
Cursor = crVSplit Cursor = crVSplit
Left = 0 Left = 0
Height = 5 Height = 5
Top = 191 Top = 200
Width = 517 Width = 517
Align = alTop Align = alTop
ResizeAnchor = akTop ResizeAnchor = akTop
end end
object PageControl1: TPageControl[3]
Left = 0
Height = 200
Top = 0
Width = 517
ActivePage = TabSheet1
Align = alTop
TabIndex = 0
TabOrder = 3
object TabSheet1: TTabSheet
Caption = 'Call stack'
ClientHeight = 164
ClientWidth = 509
object lstCallStack: TListView
Left = 0
Height = 164
Hint = 'call stack'
Top = 0
Width = 509
Align = alClient
Columns = <
item
AutoSize = True
Caption = 'function'
Width = 62
end
item
AutoSize = True
Caption = 'address'
Width = 59
end
item
AutoSize = True
Caption = 'filename'
Width = 367
end>
GridLines = True
ReadOnly = True
TabOrder = 0
ViewStyle = vsReport
OnDblClick = lstCallStackDblClick
end
end
object TabSheet2: TTabSheet
Caption = 'Thread list'
end
end
end end
inherited toolbar: TCEToolBar inherited toolbar: TCEToolBar
Width = 509 Width = 509

View File

@ -7,7 +7,7 @@ interface
uses uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, RegExpr, ComCtrls, Classes, SysUtils, FileUtil, Forms, Controls, Graphics, RegExpr, ComCtrls,
PropEdits, GraphPropEdits, RTTIGrids, Dialogs, ExtCtrls, Menus, Buttons, PropEdits, GraphPropEdits, RTTIGrids, Dialogs, ExtCtrls, Menus, Buttons,
StdCtrls, process, fpjson, typinfo, {$IFDEF UNIX}Unix,{$ENDIF} ListViewFilterEdit, StdCtrls, process, fpjson, typinfo, Unix, ListViewFilterEdit, SynEdit,
ce_common, ce_interfaces, ce_widget, ce_processes, ce_observer, ce_synmemo, ce_common, ce_interfaces, ce_widget, ce_processes, ce_observer, ce_synmemo,
ce_sharedres, ce_stringrange, ce_dsgncontrols, ce_dialogs, ce_dbgitf, ce_sharedres, ce_stringrange, ce_dsgncontrols, ce_dialogs, ce_dbgitf,
ce_ddemangle, ce_writableComponent, EditBtn, strutils; ce_ddemangle, ce_writableComponent, EditBtn, strutils;
@ -330,9 +330,13 @@ type
btnWatch: TCEToolButton; btnWatch: TCEToolButton;
button4: TCEToolButton; button4: TCEToolButton;
Edit1: TComboBox; Edit1: TComboBox;
GroupBox1: TGroupBox;
GroupBox2: TGroupBox;
GroupBox3: TGroupBox; GroupBox3: TGroupBox;
PageControl1: TPageControl;
PageControl2: TPageControl;
TabSheet1: TTabSheet;
TabSheet2: TTabSheet;
TabSheet3: TTabSheet;
TabSheet4: TTabSheet;
varList: TListView; varList: TListView;
lstCallStack: TListView; lstCallStack: TListView;
mnuReadW: TMenuItem; mnuReadW: TMenuItem;
@ -349,6 +353,7 @@ type
Splitter2: TSplitter; Splitter2: TSplitter;
Splitter3: TSplitter; Splitter3: TSplitter;
Splitter4: TSplitter; Splitter4: TSplitter;
asmList: TListView;
varListFlt: TListViewFilterEdit; varListFlt: TListViewFilterEdit;
procedure btnContClick(Sender: TObject); procedure btnContClick(Sender: TObject);
procedure btnVariablesClick(Sender: TObject); procedure btnVariablesClick(Sender: TObject);
@ -396,6 +401,10 @@ type
fAddWatchPointKind: TAddWatchPointKind; fAddWatchPointKind: TAddWatchPointKind;
fBreakPoints: TPersistentBreakPoints; fBreakPoints: TPersistentBreakPoints;
fMenu: TMenuItem; fMenu: TMenuItem;
fLastFilename: string;
fLastFunction: string;
fLastOffset: string;
fLastLine: string;
procedure updateMenu; procedure updateMenu;
procedure optionsChangesApplied(sender: TObject); procedure optionsChangesApplied(sender: TObject);
procedure disableEditor; procedure disableEditor;
@ -413,6 +422,7 @@ type
procedure infoRegs; procedure infoRegs;
procedure infoStack; procedure infoStack;
procedure infoVariables; procedure infoVariables;
procedure infoAsm(const fname: string);
procedure sendCustomCommand; procedure sendCustomCommand;
procedure setGpr(reg: TCpuRegister; val: TCpuGprValue); procedure setGpr(reg: TCpuRegister; val: TCpuGprValue);
procedure setFpr(reg: TFpuRegister; val: extended); procedure setFpr(reg: TFpuRegister; val: extended);
@ -1660,6 +1670,18 @@ end;
procedure TCEGdbWidget.interpretJson; procedure TCEGdbWidget.interpretJson;
procedure selectAsmInstr;
var
itm: TListItem;
begin
itm := asmList.FindCaption(0, fLastOffset, false, true, false);
if itm.isNotNil then
begin
itm.Selected:=true;
itm.MakeVisible(false);
end;
end;
procedure autoGetStuff; procedure autoGetStuff;
begin begin
if fOptions.autoGetCallStack then if fOptions.autoGetCallStack then
@ -1668,6 +1690,7 @@ procedure TCEGdbWidget.interpretJson;
infoRegs; infoRegs;
if fOptions.autoGetVariables then if fOptions.autoGetVariables then
infoVariables; infoVariables;
selectAsmInstr;
end; end;
var var
@ -1681,7 +1704,6 @@ var
nme: string; nme: string;
reason: string; reason: string;
addr: PtrUint = 0; addr: PtrUint = 0;
fullname: string = '';
func:string = ''; func:string = '';
line: integer = -1; line: integer = -1;
// registers data // registers data
@ -1726,18 +1748,31 @@ begin
obj := TJSONObject(fJson.Find('frame')); obj := TJSONObject(fJson.Find('frame'));
if obj.isNotNil and (obj.JSONType = jtObject) then if obj.isNotNil and (obj.JSONType = jtObject) then
begin begin
val := obj.Find('addr');
if val.isNotNil then
fLastOffset:=val.AsString;
val := obj.Find('fullname'); val := obj.Find('fullname');
if val.isNotNil then if val.isNotNil then
fullname := val.AsString; fLastFilename := val.AsString;
val := obj.Find('line'); val := obj.Find('line');
if val.isNotNil then if val.isNotNil then
begin
line := val.AsInteger; line := val.AsInteger;
if fDocHandler.findDocument(fullname).isNil and fullname.fileExists then fLastLine := val.AsString;
fDocHandler.openDocument(fullname); end;
val := obj.Find('func');
if val.isNotNil then
begin
if val.AsString <> fLastFunction then
infoAsm(fLastFilename);
fLastFunction := val.AsString;
end;
if fDocHandler.findDocument(fLastFilename).isNil and fLastFilename.fileExists then
fDocHandler.openDocument(fLastFilename);
setState(gsPaused); setState(gsPaused);
autoGetStuff; autoGetStuff;
readOutput; readOutput;
subjDebugBreak(fSubj, fullname, line, brkreason); subjDebugBreak(fSubj, fLastFilename, line, brkreason);
end; end;
end end
@ -1762,27 +1797,37 @@ begin
obj := TJSONObject(fJson.Find('frame')); obj := TJSONObject(fJson.Find('frame'));
if obj.isNotNil and (obj.JSONType = jtObject) then if obj.isNotNil and (obj.JSONType = jtObject) then
begin begin
val := obj.Find('addr');
if val.isNotNil then
fLastOffset:=val.AsString;
val := obj.Find('fullname'); val := obj.Find('fullname');
if val.isNotNil then if val.isNotNil then
fullname := val.AsString; fLastFilename := val.AsString;
val := obj.Find('line'); val := obj.Find('line');
if val.isNotNil then if val.isNotNil then
line := val.AsInteger; line := val.AsInteger;
val := obj.Find('func');
if val.isNotNil then
begin
if val.AsString <> fLastFunction then
infoAsm(fLastFilename);
fLastFunction := val.AsString;
end;
end; end;
if fCatchPause then if fCatchPause then
begin begin
fCatchPause := false; fCatchPause := false;
if fDocHandler.findDocument(fullname).isNil and fullname.fileExists then if fDocHandler.findDocument(fLastFilename).isNil and fLastFilename.fileExists then
fDocHandler.openDocument(fullname); fDocHandler.openDocument(fLastFilename);
autoGetStuff; autoGetStuff;
setState(gsPaused); setState(gsPaused);
readOutput; readOutput;
subjDebugBreak(fSubj, fullname, line, dbSignal); subjDebugBreak(fSubj, fLastFilename, line, dbSignal);
end end
else else
begin begin
if dlgYesNo(format('The signal %s (%s) was received on line %d of file %s .' if dlgYesNo(format('The signal %s (%s) was received on line %d of file %s .'
+ LineEnding + 'Do you wish to pause execution ?', [signame, sigmean, line, fullname]), + LineEnding + 'Do you wish to pause execution ?', [signame, sigmean, line, fLastFilename]),
'Unexpected signal received') = mrNo then 'Unexpected signal received') = mrNo then
begin begin
gdbCommand('continue', @gdboutJsonize); gdbCommand('continue', @gdboutJsonize);
@ -1790,12 +1835,12 @@ begin
end end
else else
begin begin
if not fDocHandler.findDocument(fullname).isNil and fullname.fileExists then if not fDocHandler.findDocument(fLastFilename).isNil and fLastFilename.fileExists then
fDocHandler.openDocument(fullname); fDocHandler.openDocument(fLastFilename);
autoGetStuff; autoGetStuff;
setState(gsPaused); setState(gsPaused);
readOutput; readOutput;
subjDebugBreak(fSubj, fullname, line, dbSignal); subjDebugBreak(fSubj, fLastFilename, line, dbSignal);
end; end;
end; end;
end end
@ -1884,7 +1929,7 @@ begin
break; break;
val := obj.Find('fullname'); val := obj.Find('fullname');
if val.isNotNil then if val.isNotNil then
fullname:= val.AsString; fLastFilename:= val.AsString;
val := obj.Find('func'); val := obj.Find('func');
if val.isNotNil then if val.isNotNil then
begin begin
@ -1899,7 +1944,7 @@ begin
val := obj.Find('line'); val := obj.Find('line');
if val.isNotNil then if val.isNotNil then
line := val.AsInteger; line := val.AsInteger;
fStackItems.addItem(addr, fullname, func, line); fStackItems.addItem(addr, fLastFilename, func, line);
end; end;
fStackItems.assignToList(lstCallStack); fStackItems.assignToList(lstCallStack);
end; end;
@ -1935,6 +1980,38 @@ begin
varList.EndUpdate; varList.EndUpdate;
end; end;
val := fJson.Find('asm_insns');
if val.isNotNil and (val.JSONType = jtArray) then
begin
asmList.Clear;
asmList.BeginUpdate;
arr := TJSONArray(val);
for i := 0 to arr.Count-1 do
begin
obj := arr.Objects[i];
val := obj.Find('address');
if val.isNotNil then
nme := val.AsString;
//val := obj.Find('func-name');
//val := obj.Find('offset');
val := obj.Find('inst');
if val.isNotNil then
begin
asmList.AddItem(nme, nil);
if nme = fLastOffset then
asmList.Selected := asmList.Items[asmList.Items.Count-1];
if fOptions.autoDemangle then
asmList.Items[asmList.Items.Count-1].SubItems.Add(demangle(val.AsString))
else
asmList.Items[asmList.Items.Count-1].SubItems.Add(val.AsString);
end;
end;
if asmList.Selected.isNotNil then
asmList.Selected.MakeVisible(false);
asmList.EndUpdate;
selectAsmInstr;
end;
if fOptions.showGdbOutput or fShowFromCustomCommand then if fOptions.showGdbOutput or fShowFromCustomCommand then
begin begin
fShowFromCustomCommand := false; fShowFromCustomCommand := false;
@ -2042,6 +2119,15 @@ begin
gdbCommand('-stack-list-variables --skip-unavailable --simple-values'); gdbCommand('-stack-list-variables --skip-unavailable --simple-values');
end; end;
procedure TCEGdbWidget.infoAsm(const fname: string);
var
cmd: string;
begin
cmd := format('-data-disassemble -f %s -l %s -n -1 -- 0', [fname, fLastLine]);
//cmd := format('-data-disassemble -s %s -e $pc -- 0', [fLastOffset]);
gdbCommand(cmd, @gdboutJsonize);
end;
procedure TCEGdbWidget.btnStartClick(Sender: TObject); procedure TCEGdbWidget.btnStartClick(Sender: TObject);
begin begin
startDebugging; startDebugging;