#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,21 +54,33 @@ inherited CEGdbWidget: TCEGdbWidget
ValueFont.Color = clMaroon ValueFont.Color = clMaroon
end end
end end
object GroupBox2: TGroupBox object Splitter4: TSplitter
Cursor = crVSplit
Left = 0 Left = 0
Height = 191 Height = 6
Top = 0 Top = 0
Width = 517 Width = 517
Align = alTop Align = alTop
ResizeAnchor = akTop
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' Caption = 'Variables'
ClientHeight = 161 ClientHeight = 164
ClientWidth = 513 ClientWidth = 509
TabOrder = 1
object varList: TListView object varList: TListView
Left = 2 Left = 2
Height = 135 Height = 138
Top = 24 Top = 24
Width = 509 Width = 505
Align = alClient Align = alClient
BorderSpacing.Around = 2 BorderSpacing.Around = 2
Columns = < Columns = <
@ -81,7 +92,7 @@ inherited CEGdbWidget: TCEGdbWidget
item item
AutoSize = True AutoSize = True
Caption = 'Value' Caption = 'Value'
Width = 458 Width = 454
end> end>
GridLines = True GridLines = True
HideSelection = False HideSelection = False
@ -97,7 +108,7 @@ inherited CEGdbWidget: TCEGdbWidget
Height = 20 Height = 20
Hint = 'locate variables' Hint = 'locate variables'
Top = 2 Top = 2
Width = 509 Width = 505
ButtonWidth = 24 ButtonWidth = 24
NumGlyphs = 1 NumGlyphs = 1
Align = alTop Align = alTop
@ -107,14 +118,38 @@ inherited CEGdbWidget: TCEGdbWidget
OnChange = varListFltChange OnChange = varListFltChange
end end
end end
object Splitter4: TSplitter object TabSheet4: TTabSheet
Cursor = crVSplit Caption = 'Assembly'
Left = 0 ClientHeight = 164
Height = 6 ClientWidth = 509
Top = 191 object asmList: TListView
Width = 517 Left = 2
Align = alTop Height = 160
ResizeAnchor = akTop 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 end
object Panel3: TPanel[1] object Panel3: TPanel[1]
@ -152,22 +187,34 @@ inherited CEGdbWidget: TCEGdbWidget
TabOrder = 0 TabOrder = 0
end end
end end
object GroupBox1: TGroupBox[2] object Splitter3: TSplitter[2]
Cursor = crVSplit
Left = 0 Left = 0
Height = 191 Height = 5
Top = 0 Top = 200
Width = 517 Width = 517
Align = alTop Align = alTop
ResizeAnchor = akTop
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' Caption = 'Call stack'
ClientHeight = 161 ClientHeight = 164
ClientWidth = 513 ClientWidth = 509
TabOrder = 2
object lstCallStack: TListView object lstCallStack: TListView
Left = 0 Left = 0
Height = 161 Height = 164
Hint = 'call stack' Hint = 'call stack'
Top = 0 Top = 0
Width = 513 Width = 509
Align = alClient Align = alClient
Columns = < Columns = <
item item
@ -183,7 +230,7 @@ inherited CEGdbWidget: TCEGdbWidget
item item
AutoSize = True AutoSize = True
Caption = 'filename' Caption = 'filename'
Width = 371 Width = 367
end> end>
GridLines = True GridLines = True
ReadOnly = True ReadOnly = True
@ -192,14 +239,9 @@ inherited CEGdbWidget: TCEGdbWidget
OnDblClick = lstCallStackDblClick OnDblClick = lstCallStackDblClick
end end
end end
object Splitter3: TSplitter[3] object TabSheet2: TTabSheet
Cursor = crVSplit Caption = 'Thread list'
Left = 0 end
Height = 5
Top = 191
Width = 517
Align = alTop
ResizeAnchor = akTop
end end
end end
inherited toolbar: TCEToolBar inherited toolbar: TCEToolBar

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;