#97, add thread list

This commit is contained in:
Basile Burg 2016-11-28 02:06:03 +01:00
parent 609303c983
commit 691b54e672
No known key found for this signature in database
GPG Key ID: 1868039F415CB8CF
2 changed files with 157 additions and 22 deletions

View File

@ -1,7 +1,7 @@
inherited CEGdbWidget: TCEGdbWidget inherited CEGdbWidget: TCEGdbWidget
Left = 635 Left = 1383
Height = 668 Height = 668
Top = 212 Top = 333
Width = 517 Width = 517
Caption = 'GDB commander' Caption = 'GDB commander'
ClientHeight = 668 ClientHeight = 668
@ -68,9 +68,9 @@ inherited CEGdbWidget: TCEGdbWidget
Height = 200 Height = 200
Top = 6 Top = 6
Width = 517 Width = 517
ActivePage = TabSheet4 ActivePage = TabSheet3
Align = alTop Align = alTop
TabIndex = 1 TabIndex = 0
TabOrder = 2 TabOrder = 2
object TabSheet3: TTabSheet object TabSheet3: TTabSheet
Caption = 'Variables' Caption = 'Variables'
@ -86,13 +86,13 @@ inherited CEGdbWidget: TCEGdbWidget
Columns = < Columns = <
item item
AutoSize = True AutoSize = True
Caption = 'Name' Caption = 'name'
Width = 47 Width = 46
end end
item item
AutoSize = True AutoSize = True
Caption = 'Value' Caption = 'value'
Width = 454 Width = 455
end> end>
GridLines = True GridLines = True
HideSelection = False HideSelection = False
@ -109,10 +109,12 @@ inherited CEGdbWidget: TCEGdbWidget
Hint = 'locate variables' Hint = 'locate variables'
Top = 2 Top = 2
Width = 505 Width = 505
UseFormActivate = True
ButtonWidth = 24 ButtonWidth = 24
NumGlyphs = 1 NumGlyphs = 1
Align = alTop Align = alTop
BorderSpacing.Around = 2 BorderSpacing.Around = 2
AutoSelect = False
MaxLength = 0 MaxLength = 0
TabOrder = 1 TabOrder = 1
OnChange = varListFltChange OnChange = varListFltChange
@ -133,13 +135,13 @@ inherited CEGdbWidget: TCEGdbWidget
Columns = < Columns = <
item item
AutoSize = True AutoSize = True
Caption = 'Address' Caption = 'address'
Width = 60 Width = 59
end end
item item
AutoSize = True AutoSize = True
Caption = 'Instruction' Caption = 'instruction'
Width = 441 Width = 442
end> end>
GridLines = True GridLines = True
HideSelection = False HideSelection = False
@ -241,6 +243,57 @@ inherited CEGdbWidget: TCEGdbWidget
end end
object TabSheet2: TTabSheet object TabSheet2: TTabSheet
Caption = 'Thread list' Caption = 'Thread list'
ClientHeight = 164
ClientWidth = 509
object lstThreads: TListView
Left = 0
Height = 164
Hint = 'call stack'
Top = 0
Width = 509
Align = alClient
Columns = <
item
AutoSize = True
Caption = 'id'
Width = 23
end
item
AutoSize = True
Caption = 'state'
Width = 42
end
item
AutoSize = True
Caption = 'core'
Width = 38
end
item
AutoSize = True
Caption = 'function'
Width = 62
end
item
AutoSize = True
Caption = 'address'
Width = 59
end
item
AutoSize = True
Caption = 'filename'
Width = 64
end
item
AutoSize = True
Caption = 'line'
Width = 200
end>
GridLines = True
ReadOnly = True
TabOrder = 0
ViewStyle = vsReport
OnDblClick = lstThreadsDblClick
end
end end
end end
end end

View File

@ -213,8 +213,6 @@ type
procedure clear; procedure clear;
end; end;
// TODO-cGDB: assembly view
// serializable breakpoint // serializable breakpoint
TPersistentBreakPoint = class(TCollectionItem) TPersistentBreakPoint = class(TCollectionItem)
strict private strict private
@ -267,6 +265,8 @@ type
TCEDebugOptionsBase = class(TWritableLfmTextComponent) TCEDebugOptionsBase = class(TWritableLfmTextComponent)
private private
fAutoDisassemble: boolean;
fAutoGetThreads: boolean;
fAutoDemangle: boolean; fAutoDemangle: boolean;
fAutoGetCallStack: boolean; fAutoGetCallStack: boolean;
fAutoGetRegisters: boolean; fAutoGetRegisters: boolean;
@ -281,10 +281,12 @@ type
procedure setCommandsHistory(value: TStringList); procedure setCommandsHistory(value: TStringList);
procedure setShortcuts(value: TCEDebugShortcuts); procedure setShortcuts(value: TCEDebugShortcuts);
published published
property autoDisassemble: boolean read fAutoDisassemble write fAutoDisassemble;
property autoDemangle: boolean read fAutoDemangle write fAutoDemangle; property autoDemangle: boolean read fAutoDemangle write fAutoDemangle;
property autoGetCallStack: boolean read fAutoGetCallStack write fAutoGetCallStack; property autoGetCallStack: boolean read fAutoGetCallStack write fAutoGetCallStack;
property autoGetRegisters: boolean read fAutoGetRegisters write fAutoGetRegisters; property autoGetRegisters: boolean read fAutoGetRegisters write fAutoGetRegisters;
property autoGetVariables: boolean read fAutoGetVariables write fAutoGetVariables; property autoGetVariables: boolean read fAutoGetVariables write fAutoGetVariables;
property autoGetThreads: boolean read fAutoGetThreads write fAutoGetThreads;
property commandsHistory: TStringList read fCommandsHistory write setCommandsHistory; property commandsHistory: TStringList read fCommandsHistory write setCommandsHistory;
property ignoredSignals: TStringList read fIgnoredSignals write setIgnoredSignals; property ignoredSignals: TStringList read fIgnoredSignals write setIgnoredSignals;
property shortcuts: TCEDebugShortcuts read fShortcuts write setShortcuts; property shortcuts: TCEDebugShortcuts read fShortcuts write setShortcuts;
@ -331,6 +333,7 @@ type
button4: TCEToolButton; button4: TCEToolButton;
Edit1: TComboBox; Edit1: TComboBox;
GroupBox3: TGroupBox; GroupBox3: TGroupBox;
lstThreads: TListView;
PageControl1: TPageControl; PageControl1: TPageControl;
PageControl2: TPageControl; PageControl2: TPageControl;
TabSheet1: TTabSheet; TabSheet1: TTabSheet;
@ -368,6 +371,7 @@ type
procedure btnWatchClick(Sender: TObject); procedure btnWatchClick(Sender: TObject);
procedure Edit1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); procedure Edit1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
procedure lstCallStackDblClick(Sender: TObject); procedure lstCallStackDblClick(Sender: TObject);
procedure lstThreadsDblClick(Sender: TObject);
procedure mnuReadWClick(Sender: TObject); procedure mnuReadWClick(Sender: TObject);
procedure mnuReadWriteWClick(Sender: TObject); procedure mnuReadWriteWClick(Sender: TObject);
procedure mnuSelProjClick(Sender: TObject); procedure mnuSelProjClick(Sender: TObject);
@ -422,6 +426,7 @@ type
procedure infoRegs; procedure infoRegs;
procedure infoStack; procedure infoStack;
procedure infoVariables; procedure infoVariables;
procedure infoThreads;
procedure infoAsm(const fname: string); procedure infoAsm(const fname: string);
procedure sendCustomCommand; procedure sendCustomCommand;
procedure setGpr(reg: TCpuRegister; val: TCpuGprValue); procedure setGpr(reg: TCpuRegister; val: TCpuGprValue);
@ -528,6 +533,8 @@ begin
fAutoGetCallStack:= true; fAutoGetCallStack:= true;
fAutoGetRegisters:= true; fAutoGetRegisters:= true;
fAutoGetVariables:= true; fAutoGetVariables:= true;
fAutoDisassemble:= true;
fAutoGetThreads:=true;
fShowGdbOutput:=true; fShowGdbOutput:=true;
fIgnoredSignals := TStringList.Create; fIgnoredSignals := TStringList.Create;
fIgnoredSignals.Duplicates:= dupIgnore; fIgnoredSignals.Duplicates:= dupIgnore;
@ -569,6 +576,8 @@ begin
begin begin
src := TCEDebugOptionsBase(source); src := TCEDebugOptionsBase(source);
fAutoDemangle:=src.fAutoDemangle; fAutoDemangle:=src.fAutoDemangle;
fAutoDisassemble:=src.fAutoDisassemble;
fAutoGetThreads:=src.fAutoGetThreads;
fAutoGetCallStack:=src.fAutoGetCallStack; fAutoGetCallStack:=src.fAutoGetCallStack;
fAutoGetRegisters:=src.fAutoGetRegisters; fAutoGetRegisters:=src.fAutoGetRegisters;
fAutoGetVariables:=src.autoGetVariables; fAutoGetVariables:=src.autoGetVariables;
@ -1690,12 +1699,14 @@ procedure TCEGdbWidget.interpretJson;
infoRegs; infoRegs;
if fOptions.autoGetVariables then if fOptions.autoGetVariables then
infoVariables; infoVariables;
if fOptions.autoGetThreads then
infoThreads;
selectAsmInstr; selectAsmInstr;
end; end;
var var
r: PString; r: PString;
i: integer; i,j: integer;
val: TJSONData; val: TJSONData;
obj: TJSONObject; obj: TJSONObject;
arr: TJSONArray; arr: TJSONArray;
@ -1741,7 +1752,10 @@ begin
begin begin
k := varList.FindCaption(0, val.AsString, false, true, false); k := varList.FindCaption(0, val.AsString, false, true, false);
if k.isNotNil then if k.isNotNil then
begin
varList.ItemIndex:=k.index; varList.ItemIndex:=k.index;
k.MakeVisible(false);
end;
end; end;
end; end;
end; end;
@ -1763,7 +1777,7 @@ begin
val := obj.Find('func'); val := obj.Find('func');
if val.isNotNil then if val.isNotNil then
begin begin
if val.AsString <> fLastFunction then if fOptions.autoDisassemble and (val.AsString <> fLastFunction) then
infoAsm(fLastFilename); infoAsm(fLastFilename);
fLastFunction := val.AsString; fLastFunction := val.AsString;
end; end;
@ -1809,7 +1823,7 @@ begin
val := obj.Find('func'); val := obj.Find('func');
if val.isNotNil then if val.isNotNil then
begin begin
if val.AsString <> fLastFunction then if fOptions.autoDisassemble and (val.AsString <> fLastFunction) then
infoAsm(fLastFilename); infoAsm(fLastFilename);
fLastFunction := val.AsString; fLastFunction := val.AsString;
end; end;
@ -1883,7 +1897,7 @@ begin
0..integer(high(TCpuRegister)): 0..integer(high(TCpuRegister)):
begin begin
fInspState.CPU.setInspectableRegister fInspState.CPU.setInspectableRegister
(TCpuRegister(number), {$IFDEF CPU64}val.AsInt64{$ELSE}val.AsInteger{$ENDIF}); (TCpuRegister(number), {$IFDEF CPU64}val.AsQWord{$ELSE}val.AsInteger{$ENDIF});
end; end;
flagOffset: flagOffset:
begin begin
@ -1954,7 +1968,7 @@ begin
val := fJson.Find('locals'); val := fJson.Find('locals');
if val.isNotNil and (val.JSONType = jtArray) then if val.isNotNil and (val.JSONType = jtArray) then
begin begin
i := varList.ItemIndex; j := varList.ItemIndex;
varList.BeginUpdate; varList.BeginUpdate;
varList.Clear; varList.Clear;
arr := TJSONArray(val); arr := TJSONArray(val);
@ -1975,16 +1989,16 @@ begin
with varList.Items[varList.Items.Count-1] do with varList.Items[varList.Items.Count-1] do
SubItems.Add(val.AsString); SubItems.Add(val.AsString);
end; end;
if (i <> -1) and (i <= varList.Items.Count) then if (j <> -1) and (j <= varList.Items.Count) then
varList.ItemIndex:=i; varList.ItemIndex := j;
varList.EndUpdate; varList.EndUpdate;
end; end;
val := fJson.Find('asm_insns'); val := fJson.Find('asm_insns');
if val.isNotNil and (val.JSONType = jtArray) then if val.isNotNil and (val.JSONType = jtArray) then
begin begin
asmList.Clear;
asmList.BeginUpdate; asmList.BeginUpdate;
asmList.Clear;
arr := TJSONArray(val); arr := TJSONArray(val);
for i := 0 to arr.Count-1 do for i := 0 to arr.Count-1 do
begin begin
@ -2012,6 +2026,51 @@ begin
selectAsmInstr; selectAsmInstr;
end; end;
val := fJson.Find('threads');
if val.isNotNil and (val.JSONType = jtArray) then
begin
arr := TJSONArray(val);
lstThreads.BeginUpdate;
lstThreads.Clear;
for i := 0 to arr.Count-1 do
begin
obj := arr.Objects[i];
val := obj.Find('id');
if val.isNotNil then
begin
lstThreads.AddItem(val.AsString, nil);
k := lstThreads.Items[lstThreads.Items.Count-1];
val := obj.Find('state');
if val.isNotNil then
k.SubItems.Add(val.AsString);
val := obj.Find('core');
if val.isNotNil then
k.SubItems.Add(val.AsString);
val := obj.Find('frame');
if val.isNotNil and (val.JSONType = jtObject) then
begin
obj := TJSONObject(val);
val := obj.Find('func');
if val.isNotNil then
if fOptions.autoDemangle then
k.SubItems.Add(demangle(val.AsString))
else
k.SubItems.Add(demangle(val.AsString));
val := obj.Find('addr');
if val.isNotNil then
k.SubItems.Add(val.AsString);
val := obj.Find('fullname');
if val.isNotNil then
k.SubItems.Add(val.AsString);
val := obj.Find('line');
if val.isNotNil then
k.SubItems.Add(val.AsString);
end;
end;
end;
lstThreads.EndUpdate;
end;
if fOptions.showGdbOutput or fShowFromCustomCommand then if fOptions.showGdbOutput or fShowFromCustomCommand then
begin begin
fShowFromCustomCommand := false; fShowFromCustomCommand := false;
@ -2119,6 +2178,11 @@ begin
gdbCommand('-stack-list-variables --skip-unavailable --simple-values'); gdbCommand('-stack-list-variables --skip-unavailable --simple-values');
end; end;
procedure TCEGdbWidget.infoThreads;
begin
gdbCommand('-thread-info');
end;
procedure TCEGdbWidget.infoAsm(const fname: string); procedure TCEGdbWidget.infoAsm(const fname: string);
var var
cmd: string; cmd: string;
@ -2230,6 +2294,24 @@ begin
infoRegs;} infoRegs;}
end; end;
procedure TCEGdbWidget.lstThreadsDblClick(Sender: TObject);
var
lne: integer;
nme: string;
doc: TCESynMemo = nil;
begin
if (lstThreads.Selected.isNil) or (lstThreads.Selected.SubItems.Count < 6) then
exit;
lne := StrToIntDef(lstThreads.Selected.SubItems[5], -1);
nme := lstThreads.Selected.SubItems[4];
if not nme.fileExists or (lne = -1) then
exit;
fDocHandler.openDocument(nme);
doc := fDocHandler.findDocument(nme);
if doc.isNotNil then
doc.CaretY:= lne;
end;
procedure TCEGdbWidget.mnuReadWClick(Sender: TObject); procedure TCEGdbWidget.mnuReadWClick(Sender: TObject);
begin begin
fAddWatchPointKind := wpkRead; fAddWatchPointKind := wpkRead;