mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-15 01:19:29 +02:00
DBG: Added Thread dialog
git-svn-id: trunk@30467 -
This commit is contained in:
parent
4b1f5f2192
commit
580a85d184
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -2776,6 +2776,8 @@ debugger/test/debugtestform.lrs svneol=native#text/pascal
|
|||||||
debugger/test/debugtestform.pp svneol=native#text/pascal
|
debugger/test/debugtestform.pp svneol=native#text/pascal
|
||||||
debugger/test/examples/testcntr.pp svneol=native#text/pascal
|
debugger/test/examples/testcntr.pp svneol=native#text/pascal
|
||||||
debugger/test/examples/testwait.pp svneol=native#text/pascal
|
debugger/test/examples/testwait.pp svneol=native#text/pascal
|
||||||
|
debugger/threaddlg.lfm svneol=native#text/plain
|
||||||
|
debugger/threaddlg.pp svneol=native#text/pascal
|
||||||
debugger/watchesdlg.lfm svneol=native#text/plain
|
debugger/watchesdlg.lfm svneol=native#text/plain
|
||||||
debugger/watchesdlg.pp svneol=native#text/pascal
|
debugger/watchesdlg.pp svneol=native#text/pascal
|
||||||
debugger/watchpropertydlg.lfm svneol=native#text/plain
|
debugger/watchpropertydlg.lfm svneol=native#text/plain
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
inherited CallStackDlg: TCallStackDlg
|
inherited CallStackDlg: TCallStackDlg
|
||||||
Left = 466
|
Left = 306
|
||||||
Height = 246
|
Height = 246
|
||||||
Top = 191
|
Top = 130
|
||||||
Width = 562
|
Width = 562
|
||||||
BorderStyle = bsSizeToolWin
|
BorderStyle = bsSizeToolWin
|
||||||
Caption = 'CallStack'
|
Caption = 'CallStack'
|
||||||
@ -60,31 +60,31 @@ inherited CallStackDlg: TCallStackDlg
|
|||||||
ShowHint = True
|
ShowHint = True
|
||||||
TabOrder = 1
|
TabOrder = 1
|
||||||
object ToolButtonShow: TToolButton
|
object ToolButtonShow: TToolButton
|
||||||
Left = 99
|
Left = 110
|
||||||
Top = 0
|
Top = 0
|
||||||
Action = actShow
|
Action = actShow
|
||||||
ImageIndex = 0
|
ImageIndex = 0
|
||||||
end
|
end
|
||||||
object ToolButtonCurrent: TToolButton
|
object ToolButtonCurrent: TToolButton
|
||||||
Left = 149
|
Left = 160
|
||||||
Top = 0
|
Top = 0
|
||||||
Action = actSetCurrent
|
Action = actSetCurrent
|
||||||
end
|
end
|
||||||
object ToolButton4: TToolButton
|
object ToolButton4: TToolButton
|
||||||
Left = 199
|
Left = 210
|
||||||
Top = 0
|
Top = 0
|
||||||
Width = 8
|
Width = 8
|
||||||
Caption = 'ToolButton4'
|
Caption = 'ToolButton4'
|
||||||
Style = tbsSeparator
|
Style = tbsSeparator
|
||||||
end
|
end
|
||||||
object ToolButtonMore: TToolButton
|
object ToolButtonMore: TToolButton
|
||||||
Left = 269
|
Left = 280
|
||||||
Top = 0
|
Top = 0
|
||||||
Action = actViewMore
|
Action = actViewMore
|
||||||
ImageIndex = 1
|
ImageIndex = 1
|
||||||
end
|
end
|
||||||
object ToolButtonMax: TToolButton
|
object ToolButtonMax: TToolButton
|
||||||
Left = 207
|
Left = 218
|
||||||
Top = 0
|
Top = 0
|
||||||
Action = actViewLimit
|
Action = actViewLimit
|
||||||
Caption = 'Max 10'
|
Caption = 'Max 10'
|
||||||
@ -92,7 +92,7 @@ inherited CallStackDlg: TCallStackDlg
|
|||||||
Style = tbsDropDown
|
Style = tbsDropDown
|
||||||
end
|
end
|
||||||
object ToolButtonGoto: TToolButton
|
object ToolButtonGoto: TToolButton
|
||||||
Left = 477
|
Left = 488
|
||||||
Top = 0
|
Top = 0
|
||||||
Action = actViewGoto
|
Action = actViewGoto
|
||||||
ImageIndex = 4
|
ImageIndex = 4
|
||||||
@ -104,33 +104,33 @@ inherited CallStackDlg: TCallStackDlg
|
|||||||
ImageIndex = 5
|
ImageIndex = 5
|
||||||
end
|
end
|
||||||
object ToolButton8: TToolButton
|
object ToolButton8: TToolButton
|
||||||
Left = 91
|
Left = 102
|
||||||
Top = 0
|
Top = 0
|
||||||
Width = 8
|
Width = 8
|
||||||
Caption = 'ToolButton8'
|
Caption = 'ToolButton8'
|
||||||
Style = tbsSeparator
|
Style = tbsSeparator
|
||||||
end
|
end
|
||||||
object ToolButton9: TToolButton
|
object ToolButton9: TToolButton
|
||||||
Left = 319
|
Left = 330
|
||||||
Top = 0
|
Top = 0
|
||||||
Width = 8
|
Width = 8
|
||||||
Caption = 'ToolButton9'
|
Caption = 'ToolButton9'
|
||||||
Style = tbsSeparator
|
Style = tbsSeparator
|
||||||
end
|
end
|
||||||
object ToolButtonTop: TToolButton
|
object ToolButtonTop: TToolButton
|
||||||
Left = 327
|
Left = 338
|
||||||
Top = 0
|
Top = 0
|
||||||
Action = actViewTop
|
Action = actViewTop
|
||||||
ImageIndex = 2
|
ImageIndex = 2
|
||||||
end
|
end
|
||||||
object ToolButtonBottom: TToolButton
|
object ToolButtonBottom: TToolButton
|
||||||
Left = 377
|
Left = 388
|
||||||
Top = 0
|
Top = 0
|
||||||
Action = actViewBottom
|
Action = actViewBottom
|
||||||
ImageIndex = 3
|
ImageIndex = 3
|
||||||
end
|
end
|
||||||
object Panel1: TPanel
|
object Panel1: TPanel
|
||||||
Left = 427
|
Left = 438
|
||||||
Height = 40
|
Height = 40
|
||||||
Top = 0
|
Top = 0
|
||||||
Width = 50
|
Width = 50
|
||||||
@ -140,7 +140,7 @@ inherited CallStackDlg: TCallStackDlg
|
|||||||
TabOrder = 0
|
TabOrder = 0
|
||||||
object txtGoto: TEdit
|
object txtGoto: TEdit
|
||||||
Left = 2
|
Left = 2
|
||||||
Height = 21
|
Height = 23
|
||||||
Top = 8
|
Top = 8
|
||||||
Width = 46
|
Width = 46
|
||||||
OnKeyPress = txtGotoKeyPress
|
OnKeyPress = txtGotoKeyPress
|
||||||
@ -159,7 +159,7 @@ inherited CallStackDlg: TCallStackDlg
|
|||||||
Style = tbsCheck
|
Style = tbsCheck
|
||||||
end
|
end
|
||||||
object ToolButton2: TToolButton
|
object ToolButton2: TToolButton
|
||||||
Left = 527
|
Left = 538
|
||||||
Top = 0
|
Top = 0
|
||||||
Width = 8
|
Width = 8
|
||||||
Caption = 'ToolButton2'
|
Caption = 'ToolButton2'
|
||||||
|
@ -719,20 +719,8 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
function TCallStackDlg.GetFunction(const Entry: TCallStackEntry): string;
|
function TCallStackDlg.GetFunction(const Entry: TCallStackEntry): string;
|
||||||
var
|
|
||||||
S: String;
|
|
||||||
m: Integer;
|
|
||||||
begin
|
begin
|
||||||
S := '';
|
Result := Entry.GetFunctionWithArg;
|
||||||
for m := 0 to Entry.ArgumentCount - 1 do
|
|
||||||
begin
|
|
||||||
if S <> '' then
|
|
||||||
S := S + ', ';
|
|
||||||
S := S + Entry.ArgumentValues[m];
|
|
||||||
end;
|
|
||||||
if S <> '' then
|
|
||||||
S := '(' + S + ')';
|
|
||||||
Result := Entry.FunctionName + S;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCallStackDlg.GotoIndex(AIndex: Integer);
|
procedure TCallStackDlg.GotoIndex(AIndex: Integer);
|
||||||
|
@ -169,6 +169,41 @@ type
|
|||||||
procedure ReleaseReference;
|
procedure ReleaseReference;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
TDebuggerChangeNotification = class(TDebuggerNotification)
|
||||||
|
private
|
||||||
|
FOnChange: TNotifyEvent;
|
||||||
|
public
|
||||||
|
property OnChange: TNotifyEvent read FOnChange write FOnChange;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TDebuggerNotificationList }
|
||||||
|
|
||||||
|
TDebuggerNotificationList = class(TObject)
|
||||||
|
private
|
||||||
|
FList: TList;
|
||||||
|
function GetItem(AIndex: Integer): TDebuggerNotification;
|
||||||
|
protected
|
||||||
|
function NextDownIndex(var Index: integer): boolean;
|
||||||
|
public
|
||||||
|
constructor Create;
|
||||||
|
destructor Destroy; override;
|
||||||
|
procedure Add(const ANotification: TDebuggerNotification);
|
||||||
|
procedure Remove(const ANotification: TDebuggerNotification);
|
||||||
|
function Count: Integer;
|
||||||
|
procedure Clear;
|
||||||
|
property Items[AIndex: Integer]: TDebuggerNotification read GetItem; default;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TDebuggerChangeNotificationList }
|
||||||
|
|
||||||
|
TDebuggerChangeNotificationList = class(TDebuggerNotificationList)
|
||||||
|
private
|
||||||
|
function GetItem(AIndex: Integer): TDebuggerChangeNotification; reintroduce;
|
||||||
|
public
|
||||||
|
procedure NotifyChange(Sender: TObject);
|
||||||
|
property Items[AIndex: Integer]: TDebuggerChangeNotification read GetItem; default;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
TIDEBreakPoints = class;
|
TIDEBreakPoints = class;
|
||||||
TIDEBreakPointGroup = class;
|
TIDEBreakPointGroup = class;
|
||||||
@ -578,14 +613,13 @@ type
|
|||||||
property Result: TDBGType read FResult;
|
property Result: TDBGType read FResult;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{%region Watches **************************************************************
|
||||||
(******************************************************************************)
|
******************************************************************************
|
||||||
(******************************************************************************)
|
** **
|
||||||
(** **)
|
** W A T C H E S **
|
||||||
(** W A T C H E S **)
|
** **
|
||||||
(** **)
|
******************************************************************************
|
||||||
(******************************************************************************)
|
******************************************************************************}
|
||||||
(******************************************************************************)
|
|
||||||
|
|
||||||
TWatchDisplayFormat =
|
TWatchDisplayFormat =
|
||||||
(wdfDefault,
|
(wdfDefault,
|
||||||
@ -741,7 +775,7 @@ type
|
|||||||
private
|
private
|
||||||
FDebugger: TDebugger; // reference to our debugger
|
FDebugger: TDebugger; // reference to our debugger
|
||||||
FOnChange: TNotifyEvent;
|
FOnChange: TNotifyEvent;
|
||||||
function GetItem(const AnIndex: Integer): TDBGWatch;
|
function GetItem(const AnIndex: Integer): TDBGWatch;
|
||||||
procedure SetItem(const AnIndex: Integer; const AValue: TDBGWatch);
|
procedure SetItem(const AnIndex: Integer; const AValue: TDBGWatch);
|
||||||
protected
|
protected
|
||||||
procedure DoStateChange(const AOldState: TDBGState); virtual;
|
procedure DoStateChange(const AOldState: TDBGState); virtual;
|
||||||
@ -758,14 +792,15 @@ type
|
|||||||
write SetItem; default;
|
write SetItem; default;
|
||||||
property OnChange: TNotifyEvent read FOnChange write FOnChange;
|
property OnChange: TNotifyEvent read FOnChange write FOnChange;
|
||||||
end;
|
end;
|
||||||
|
{%endregion ^^^^^ Watches ^^^^^ }
|
||||||
|
|
||||||
(******************************************************************************)
|
{%region Locals ***************************************************************
|
||||||
(******************************************************************************)
|
******************************************************************************
|
||||||
(** **)
|
** **
|
||||||
(** L O C A L S **)
|
** L O C A L S **
|
||||||
(** **)
|
** **
|
||||||
(******************************************************************************)
|
******************************************************************************
|
||||||
(******************************************************************************)
|
******************************************************************************}
|
||||||
|
|
||||||
{ TBaseLocals }
|
{ TBaseLocals }
|
||||||
|
|
||||||
@ -820,15 +855,16 @@ type
|
|||||||
constructor Create(const ADebugger: TDebugger);
|
constructor Create(const ADebugger: TDebugger);
|
||||||
property OnChange: TNotifyEvent read FOnChange write FOnChange;
|
property OnChange: TNotifyEvent read FOnChange write FOnChange;
|
||||||
end;
|
end;
|
||||||
|
{%endregion ^^^^^ Locals ^^^^^ }
|
||||||
|
|
||||||
|
|
||||||
(******************************************************************************)
|
{%region Line Info ************************************************************
|
||||||
(******************************************************************************)
|
******************************************************************************
|
||||||
(** **)
|
** **
|
||||||
(** L I N E I N F O **)
|
** L I N E I N F O **
|
||||||
(** **)
|
** **
|
||||||
(******************************************************************************)
|
******************************************************************************
|
||||||
(******************************************************************************)
|
******************************************************************************}
|
||||||
|
|
||||||
TIDELineInfoEvent = procedure(const ASender: TObject; const ASource: String) of object;
|
TIDELineInfoEvent = procedure(const ASender: TObject; const ASource: String) of object;
|
||||||
{ TBaseLineInfo }
|
{ TBaseLineInfo }
|
||||||
@ -884,15 +920,15 @@ type
|
|||||||
constructor Create(const ADebugger: TDebugger);
|
constructor Create(const ADebugger: TDebugger);
|
||||||
property OnChange: TIDELineInfoEvent read FOnChange write FOnChange;
|
property OnChange: TIDELineInfoEvent read FOnChange write FOnChange;
|
||||||
end;
|
end;
|
||||||
|
{%endregion ^^^^^ Line Info ^^^^^ }
|
||||||
|
|
||||||
{%region ^^^^^ Register ^^^^^ }
|
{%region Register *************************************************************
|
||||||
(******************************************************************************)
|
******************************************************************************
|
||||||
(******************************************************************************)
|
** **
|
||||||
(** **)
|
** R E G I S T E R S **
|
||||||
(** R E G I S T E R S **)
|
** **
|
||||||
(** **)
|
******************************************************************************
|
||||||
(******************************************************************************)
|
******************************************************************************}
|
||||||
(******************************************************************************)
|
|
||||||
|
|
||||||
{ TBaseRegisters }
|
{ TBaseRegisters }
|
||||||
|
|
||||||
@ -962,18 +998,18 @@ type
|
|||||||
end;
|
end;
|
||||||
{%endregion ^^^^^ Register ^^^^^ }
|
{%endregion ^^^^^ Register ^^^^^ }
|
||||||
|
|
||||||
(******************************************************************************)
|
{%region Callstack ************************************************************
|
||||||
(******************************************************************************)
|
******************************************************************************
|
||||||
(** **)
|
** **
|
||||||
(** C A L L S T A C K **)
|
** C A L L S T A C K **
|
||||||
(** **)
|
** **
|
||||||
(******************************************************************************)
|
******************************************************************************
|
||||||
(******************************************************************************)
|
******************************************************************************
|
||||||
(* The entries for the callstack are created on demand. This way when the *)
|
* The entries for the callstack are created on demand. This way when the *
|
||||||
(* first entry is needed, it isn't required to create the whole stack *)
|
* first entry is needed, it isn't required to create the whole stack *
|
||||||
(* *)
|
* *
|
||||||
(* TCallStackEntry needs to stay a readonly object so its data can be shared *)
|
* TCallStackEntry needs to stay a readonly object so its data can be shared *
|
||||||
(******************************************************************************)
|
******************************************************************************}
|
||||||
|
|
||||||
TBaseCallStack = class;
|
TBaseCallStack = class;
|
||||||
|
|
||||||
@ -1007,6 +1043,7 @@ type
|
|||||||
const ALine: Integer; AState: TCallStackEntryState = cseValid);
|
const ALine: Integer; AState: TCallStackEntryState = cseValid);
|
||||||
constructor CreateCopy(const ASource: TCallStackEntry);
|
constructor CreateCopy(const ASource: TCallStackEntry);
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
|
function GetFunctionWithArg: String;
|
||||||
property Address: TDbgPtr read FAdress;
|
property Address: TDbgPtr read FAdress;
|
||||||
property ArgumentCount: Integer read GetArgumentCount;
|
property ArgumentCount: Integer read GetArgumentCount;
|
||||||
property ArgumentNames[const AnIndex: Integer]: String read GetArgumentName;
|
property ArgumentNames[const AnIndex: Integer]: String read GetArgumentName;
|
||||||
@ -1098,6 +1135,7 @@ type
|
|||||||
property OnClear: TNotifyEvent read FOnClear write FOnClear;
|
property OnClear: TNotifyEvent read FOnClear write FOnClear;
|
||||||
property OnCurrent: TNotifyEvent read FOnCurrent write FOnCurrent;
|
property OnCurrent: TNotifyEvent read FOnCurrent write FOnCurrent;
|
||||||
end;
|
end;
|
||||||
|
{%endregion ^^^^^ Callstack ^^^^^ }
|
||||||
|
|
||||||
{%region ***** Disassembler ***** }
|
{%region ***** Disassembler ***** }
|
||||||
(******************************************************************************)
|
(******************************************************************************)
|
||||||
@ -1282,6 +1320,105 @@ type
|
|||||||
|
|
||||||
{%endregion ^^^^^ Disassembler ^^^^^ }
|
{%endregion ^^^^^ Disassembler ^^^^^ }
|
||||||
|
|
||||||
|
{%region Threads **************************************************************
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** T H R E A D S **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
******************************************************************************}
|
||||||
|
|
||||||
|
{ TIDEThreadsNotification }
|
||||||
|
|
||||||
|
TIDEThreadsNotification = class(TDebuggerChangeNotification)
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TDBGThreadEntry }
|
||||||
|
|
||||||
|
TDBGThreadEntry = class(TCallStackEntry)
|
||||||
|
private
|
||||||
|
FThreadId: Integer;
|
||||||
|
FThreadName: String;
|
||||||
|
FThreadState: String;
|
||||||
|
public
|
||||||
|
constructor Create(const AIndex:Integer; const AnAdress: TDbgPtr;
|
||||||
|
const AnArguments: TStrings; const AFunctionName: String;
|
||||||
|
const ASource: String; const AFullFileName: String;
|
||||||
|
const ALine: Integer;
|
||||||
|
const AThreadId: Integer; const AThreadName: String;
|
||||||
|
const AThreadState: String;
|
||||||
|
AState: TCallStackEntryState = cseValid);
|
||||||
|
constructor CreateCopy(const ASource: TDBGThreadEntry);
|
||||||
|
property ThreadId: Integer read FThreadId;
|
||||||
|
property ThreadName: String read FThreadName;
|
||||||
|
property ThreadState: String read FThreadState;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TBaseThreads }
|
||||||
|
|
||||||
|
TBaseThreads = class(TObject)
|
||||||
|
private
|
||||||
|
FCurrentThreadId: Integer;
|
||||||
|
FList: TList;
|
||||||
|
function GetEntry(const AnIndex: Integer): TDBGThreadEntry;
|
||||||
|
procedure SetCurrentThreadId(const AValue: Integer); virtual;
|
||||||
|
protected
|
||||||
|
procedure Assign(AOther: TBaseThreads);
|
||||||
|
public
|
||||||
|
constructor Create;
|
||||||
|
destructor Destroy; override;
|
||||||
|
function Count: Integer; virtual;
|
||||||
|
procedure Clear;
|
||||||
|
procedure Add(AThread: TDBGThreadEntry);
|
||||||
|
property Entries[const AnIndex: Integer]: TDBGThreadEntry read GetEntry; default;
|
||||||
|
property CurrentThreadId: Integer read FCurrentThreadId write SetCurrentThreadId;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TDBGThreads = class;
|
||||||
|
|
||||||
|
TIDEThreads = class(TBaseThreads)
|
||||||
|
private
|
||||||
|
FNotificationList: TDebuggerChangeNotificationList;
|
||||||
|
FMaster: TDBGThreads;
|
||||||
|
FDataValid: Boolean;
|
||||||
|
procedure SetMaster(const AValue: TDBGThreads);
|
||||||
|
protected
|
||||||
|
procedure MasterDestroyed;
|
||||||
|
procedure Changed;
|
||||||
|
procedure InvalidateData;
|
||||||
|
procedure ValidateData;
|
||||||
|
public
|
||||||
|
constructor Create;
|
||||||
|
destructor Destroy; override;
|
||||||
|
function Count: Integer; override;
|
||||||
|
procedure AddNotification(const ANotification: TIDEThreadsNotification);
|
||||||
|
procedure RemoveNotification(const ANotification: TIDEThreadsNotification);
|
||||||
|
procedure ChangeCurrentThread(ANewId: Integer);
|
||||||
|
property Master: TDBGThreads read FMaster write SetMaster;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TDBGThreads }
|
||||||
|
|
||||||
|
TDBGThreads = class(TObject)
|
||||||
|
private
|
||||||
|
FSlave: TIDEThreads;
|
||||||
|
FDebugger: TDebugger;
|
||||||
|
procedure SetSlave(const AValue: TIDEThreads);
|
||||||
|
protected
|
||||||
|
procedure ChangeCurrentThread(ANewId: Integer); virtual; abstract;
|
||||||
|
procedure RequestMasterData; virtual; abstract;
|
||||||
|
procedure Changed;
|
||||||
|
procedure Finished;
|
||||||
|
property Debugger: TDebugger read FDebugger write FDebugger;
|
||||||
|
public
|
||||||
|
constructor Create(const ADebugger: TDebugger);
|
||||||
|
destructor Destroy; override;
|
||||||
|
procedure DoStateChange(const AOldState: TDBGState); virtual;
|
||||||
|
property Slave: TIDEThreads read FSlave write SetSlave;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{%endregion ^^^^^ Threads ^^^^^ }
|
||||||
|
|
||||||
(******************************************************************************)
|
(******************************************************************************)
|
||||||
(******************************************************************************)
|
(******************************************************************************)
|
||||||
(** **)
|
(** **)
|
||||||
@ -1556,6 +1693,7 @@ type
|
|||||||
FState: TDBGState;
|
FState: TDBGState;
|
||||||
FCallStack: TDBGCallStack;
|
FCallStack: TDBGCallStack;
|
||||||
FWatches: TDBGWatches;
|
FWatches: TDBGWatches;
|
||||||
|
FThreads: TDBGThreads;
|
||||||
FOnCurrent: TDBGCurrentLineEvent;
|
FOnCurrent: TDBGCurrentLineEvent;
|
||||||
FOnException: TDBGExceptionEvent;
|
FOnException: TDBGExceptionEvent;
|
||||||
FOnOutput: TDBGOutputEvent;
|
FOnOutput: TDBGOutputEvent;
|
||||||
@ -1581,6 +1719,7 @@ type
|
|||||||
function CreateCallStack: TDBGCallStack; virtual;
|
function CreateCallStack: TDBGCallStack; virtual;
|
||||||
function CreateDisassembler: TDBGDisassembler; virtual;
|
function CreateDisassembler: TDBGDisassembler; virtual;
|
||||||
function CreateWatches: TDBGWatches; virtual;
|
function CreateWatches: TDBGWatches; virtual;
|
||||||
|
function CreateThreads: TDBGThreads; virtual;
|
||||||
function CreateSignals: TDBGSignals; virtual;
|
function CreateSignals: TDBGSignals; virtual;
|
||||||
function CreateExceptions: TDBGExceptions; virtual;
|
function CreateExceptions: TDBGExceptions; virtual;
|
||||||
procedure DoCurrent(const ALocation: TDBGLocationRec);
|
procedure DoCurrent(const ALocation: TDBGLocationRec);
|
||||||
@ -1662,6 +1801,7 @@ type
|
|||||||
property TargetWidth: Byte read GetTargetWidth; // Currently only 32 or 64
|
property TargetWidth: Byte read GetTargetWidth; // Currently only 32 or 64
|
||||||
property Waiting: Boolean read GetWaiting; // Set when the debugger is wating for a command to complete
|
property Waiting: Boolean read GetWaiting; // Set when the debugger is wating for a command to complete
|
||||||
property Watches: TDBGWatches read FWatches; // list of all watches etc
|
property Watches: TDBGWatches read FWatches; // list of all watches etc
|
||||||
|
property Threads: TDBGThreads read FThreads;
|
||||||
property WorkingDir: String read FWorkingDir write FWorkingDir; // The working dir of the exe being debugged
|
property WorkingDir: String read FWorkingDir write FWorkingDir; // The working dir of the exe being debugged
|
||||||
// Events
|
// Events
|
||||||
property OnCurrent: TDBGCurrentLineEvent read FOnCurrent write FOnCurrent; // Passes info about the current line being debugged
|
property OnCurrent: TDBGCurrentLineEvent read FOnCurrent write FOnCurrent; // Passes info about the current line being debugged
|
||||||
@ -1803,6 +1943,259 @@ begin
|
|||||||
Result:=bpaStop;
|
Result:=bpaStop;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TDBGThreads }
|
||||||
|
|
||||||
|
procedure TDBGThreads.SetSlave(const AValue: TIDEThreads);
|
||||||
|
begin
|
||||||
|
if FSlave = AValue then exit;
|
||||||
|
Assert((FSlave=nil) or (AValue=nil), 'TDBGThreads.Slave already set');
|
||||||
|
FSlave := AValue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TDBGThreads.Changed;
|
||||||
|
begin
|
||||||
|
If Slave <> nil then Slave.InvalidateData;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TDBGThreads.Finished;
|
||||||
|
begin
|
||||||
|
If Slave <> nil then Slave.ValidateData;
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TDBGThreads.Create(const ADebugger: TDebugger);
|
||||||
|
begin
|
||||||
|
FSlave := nil;
|
||||||
|
FDebugger := ADebugger;
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TDBGThreads.Destroy;
|
||||||
|
begin
|
||||||
|
inherited Destroy;
|
||||||
|
if FSlave <> nil then FSlave.MasterDestroyed;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TDBGThreads.DoStateChange(const AOldState: TDBGState);
|
||||||
|
begin
|
||||||
|
//
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TIDEThreads }
|
||||||
|
|
||||||
|
procedure TIDEThreads.SetMaster(const AValue: TDBGThreads);
|
||||||
|
begin
|
||||||
|
if FMaster = AValue then exit;
|
||||||
|
Assert((FMaster=nil) or (AValue=nil), 'TIDEThreads.Master already set');
|
||||||
|
if FMaster <> nil then FMaster.Slave := nil;
|
||||||
|
FMaster := AValue;
|
||||||
|
if FMaster <> nil then FMaster.Slave := self;
|
||||||
|
InvalidateData;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TIDEThreads.MasterDestroyed;
|
||||||
|
begin
|
||||||
|
Master := nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TIDEThreads.InvalidateData;
|
||||||
|
begin
|
||||||
|
FDataValid := False;
|
||||||
|
Changed;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TIDEThreads.ValidateData;
|
||||||
|
begin
|
||||||
|
FDataValid := True;
|
||||||
|
Changed;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TIDEThreads.Changed;
|
||||||
|
begin
|
||||||
|
FNotificationList.NotifyChange(Self);
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TIDEThreads.Create;
|
||||||
|
begin
|
||||||
|
inherited;
|
||||||
|
FNotificationList := TDebuggerChangeNotificationList.Create;
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TIDEThreads.Destroy;
|
||||||
|
begin
|
||||||
|
inherited Destroy;
|
||||||
|
FNotificationList.Clear;
|
||||||
|
Master := nil;
|
||||||
|
FreeAndNil(FNotificationList);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TIDEThreads.Count: Integer;
|
||||||
|
begin
|
||||||
|
if (not FDataValid) and (FMaster <> nil) then
|
||||||
|
FMaster.RequestMasterData;
|
||||||
|
|
||||||
|
if FDataValid then
|
||||||
|
Result := inherited Count
|
||||||
|
else
|
||||||
|
Result := 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TIDEThreads.AddNotification(const ANotification: TIDEThreadsNotification);
|
||||||
|
begin
|
||||||
|
FNotificationList.Add(ANotification);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TIDEThreads.RemoveNotification(const ANotification: TIDEThreadsNotification);
|
||||||
|
begin
|
||||||
|
FNotificationList.Remove(ANotification);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TIDEThreads.ChangeCurrentThread(ANewId: Integer);
|
||||||
|
begin
|
||||||
|
if FMaster <> nil then FMaster.ChangeCurrentThread(ANewId);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TDebuggerChangeNotificationList }
|
||||||
|
|
||||||
|
function TDebuggerChangeNotificationList.GetItem(AIndex: Integer): TDebuggerChangeNotification;
|
||||||
|
begin
|
||||||
|
Result := TDebuggerChangeNotification(FList[AIndex]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TDebuggerChangeNotificationList.NotifyChange(Sender: TObject);
|
||||||
|
var
|
||||||
|
i: LongInt;
|
||||||
|
begin
|
||||||
|
i := Count;
|
||||||
|
while NextDownIndex(i) do
|
||||||
|
if Assigned(Items[i]) then
|
||||||
|
Items[i].OnChange(Sender);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TDebuggerNotificationList }
|
||||||
|
|
||||||
|
function TDebuggerNotificationList.GetItem(AIndex: Integer): TDebuggerNotification;
|
||||||
|
begin
|
||||||
|
Result := TDebuggerNotification(FList[AIndex]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TDebuggerNotificationList.NextDownIndex(var Index: integer): boolean;
|
||||||
|
begin
|
||||||
|
dec(Index);
|
||||||
|
if (Index >= FList.Count) then
|
||||||
|
Index := FList.Count-1;
|
||||||
|
Result := Index >= 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TDebuggerNotificationList.Count: Integer;
|
||||||
|
begin
|
||||||
|
Result := FList.Count;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TDebuggerNotificationList.Clear;
|
||||||
|
begin
|
||||||
|
while Count > 0 do
|
||||||
|
Remove(Items[0]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TDebuggerNotificationList.Create;
|
||||||
|
begin
|
||||||
|
FList := TList.Create;
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TDebuggerNotificationList.Destroy;
|
||||||
|
begin
|
||||||
|
inherited Destroy;
|
||||||
|
Clear;
|
||||||
|
FreeAndNil(FList);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TDebuggerNotificationList.Add(const ANotification: TDebuggerNotification);
|
||||||
|
begin
|
||||||
|
FList.Add(ANotification);
|
||||||
|
ANotification.AddReference;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TDebuggerNotificationList.Remove(const ANotification: TDebuggerNotification);
|
||||||
|
begin
|
||||||
|
ANotification.ReleaseReference;
|
||||||
|
FList.Remove(ANotification);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TDBGThreadEntry }
|
||||||
|
|
||||||
|
constructor TDBGThreadEntry.Create(const AIndex: Integer; const AnAdress: TDbgPtr;
|
||||||
|
const AnArguments: TStrings; const AFunctionName: String; const ASource: String;
|
||||||
|
const AFullFileName: String; const ALine: Integer; const AThreadId: Integer;
|
||||||
|
const AThreadName: String; const AThreadState: String;
|
||||||
|
AState: TCallStackEntryState);
|
||||||
|
begin
|
||||||
|
inherited Create(AIndex, AnAdress, AnArguments, AFunctionName, ASource,
|
||||||
|
AFullFileName, ALine, AState);
|
||||||
|
FThreadId := AThreadId;
|
||||||
|
FThreadName := AThreadName;
|
||||||
|
FThreadState := AThreadState;
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TDBGThreadEntry.CreateCopy(const ASource: TDBGThreadEntry);
|
||||||
|
begin
|
||||||
|
inherited CreateCopy(ASource);
|
||||||
|
FThreadId := ASource.FThreadId;
|
||||||
|
FThreadName := ASource.FThreadName;
|
||||||
|
FThreadState := ASource.FThreadState;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TBaseThreads }
|
||||||
|
|
||||||
|
function TBaseThreads.GetEntry(const AnIndex: Integer): TDBGThreadEntry;
|
||||||
|
begin
|
||||||
|
if (AnIndex < 0) or (AnIndex >= Count) then exit(nil);
|
||||||
|
Result := TDBGThreadEntry(FList[AnIndex]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TBaseThreads.SetCurrentThreadId(const AValue: Integer);
|
||||||
|
begin
|
||||||
|
if FCurrentThreadId = AValue then exit;
|
||||||
|
FCurrentThreadId := AValue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TBaseThreads.Assign(AOther: TBaseThreads);
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
Clear;
|
||||||
|
for i := 0 to AOther.FList.Count-1 do
|
||||||
|
FList.Add(TDBGThreadEntry.CreateCopy(TDBGThreadEntry(AOther.FList[i])));
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TBaseThreads.Create;
|
||||||
|
begin
|
||||||
|
FList := TList.Create;
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TBaseThreads.Destroy;
|
||||||
|
begin
|
||||||
|
Clear;
|
||||||
|
FreeAndNil(FList);
|
||||||
|
inherited Destroy;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TBaseThreads.Count: Integer;
|
||||||
|
begin
|
||||||
|
Result := FList.Count;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TBaseThreads.Clear;
|
||||||
|
begin
|
||||||
|
while FList.Count > 0 do begin
|
||||||
|
TDBGThreadEntry(Flist[0]).Free;
|
||||||
|
FList.Delete(0);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TBaseThreads.Add(AThread: TDBGThreadEntry);
|
||||||
|
begin
|
||||||
|
FList.Add(TDBGThreadEntry.CreateCopy(AThread));
|
||||||
|
end;
|
||||||
|
|
||||||
{ TDebuggerProperties }
|
{ TDebuggerProperties }
|
||||||
|
|
||||||
constructor TDebuggerProperties.Create;
|
constructor TDebuggerProperties.Create;
|
||||||
@ -1902,6 +2295,7 @@ begin
|
|||||||
FCallStack := CreateCallStack;
|
FCallStack := CreateCallStack;
|
||||||
FDisassembler := CreateDisassembler;
|
FDisassembler := CreateDisassembler;
|
||||||
FWatches := CreateWatches;
|
FWatches := CreateWatches;
|
||||||
|
FThreads := CreateThreads;
|
||||||
FExceptions := CreateExceptions;
|
FExceptions := CreateExceptions;
|
||||||
FSignals := CreateSignals;
|
FSignals := CreateSignals;
|
||||||
FExitCode := 0;
|
FExitCode := 0;
|
||||||
@ -1957,6 +2351,11 @@ begin
|
|||||||
Result := TDBGWatches.Create(Self, TDBGWatch);
|
Result := TDBGWatches.Create(Self, TDBGWatch);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TDebugger.CreateThreads: TDBGThreads;
|
||||||
|
begin
|
||||||
|
Result := nil;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TDebugger.DebuggerEnvironmentChanged (Sender: TObject );
|
procedure TDebugger.DebuggerEnvironmentChanged (Sender: TObject );
|
||||||
begin
|
begin
|
||||||
end;
|
end;
|
||||||
@ -1984,6 +2383,7 @@ begin
|
|||||||
FCallStack.FDebugger := nil;
|
FCallStack.FDebugger := nil;
|
||||||
FDisassembler.FDebugger := nil;
|
FDisassembler.FDebugger := nil;
|
||||||
FWatches.FDebugger := nil;
|
FWatches.FDebugger := nil;
|
||||||
|
FThreads.Debugger := nil;
|
||||||
|
|
||||||
FreeAndNil(FExceptions);
|
FreeAndNil(FExceptions);
|
||||||
FreeAndNil(FBreakPoints);
|
FreeAndNil(FBreakPoints);
|
||||||
@ -1993,6 +2393,7 @@ begin
|
|||||||
FreeAndNil(FCallStack);
|
FreeAndNil(FCallStack);
|
||||||
FreeAndNil(FDisassembler);
|
FreeAndNil(FDisassembler);
|
||||||
FreeAndNil(FWatches);
|
FreeAndNil(FWatches);
|
||||||
|
FreeAndNil(FThreads);
|
||||||
FreeAndNil(FDebuggerEnvironment);
|
FreeAndNil(FDebuggerEnvironment);
|
||||||
FreeAndNil(FEnvironment);
|
FreeAndNil(FEnvironment);
|
||||||
FreeAndNil(FCurEnvironment);
|
FreeAndNil(FCurEnvironment);
|
||||||
@ -2306,6 +2707,7 @@ begin
|
|||||||
then begin
|
then begin
|
||||||
OldState := FState;
|
OldState := FState;
|
||||||
FState := AValue;
|
FState := AValue;
|
||||||
|
FThreads.DoStateChange(OldState);
|
||||||
FBreakpoints.DoStateChange(OldState);
|
FBreakpoints.DoStateChange(OldState);
|
||||||
FLocals.DoStateChange(OldState);
|
FLocals.DoStateChange(OldState);
|
||||||
FLineInfo.DoStateChange(OldState);
|
FLineInfo.DoStateChange(OldState);
|
||||||
@ -4235,6 +4637,23 @@ begin
|
|||||||
FreeAndNil(FArguments);
|
FreeAndNil(FArguments);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TCallStackEntry.GetFunctionWithArg: String;
|
||||||
|
var
|
||||||
|
S: String;
|
||||||
|
m: Integer;
|
||||||
|
begin
|
||||||
|
S := '';
|
||||||
|
for m := 0 to ArgumentCount - 1 do
|
||||||
|
begin
|
||||||
|
if S <> '' then
|
||||||
|
S := S + ', ';
|
||||||
|
S := S + ArgumentValues[m];
|
||||||
|
end;
|
||||||
|
if S <> '' then
|
||||||
|
S := '(' + S + ')';
|
||||||
|
Result := FunctionName + S;
|
||||||
|
end;
|
||||||
|
|
||||||
function TCallStackEntry.GetArgumentCount: Integer;
|
function TCallStackEntry.GetArgumentCount: Integer;
|
||||||
begin
|
begin
|
||||||
Result := FArguments.Count;
|
Result := FArguments.Count;
|
||||||
|
@ -369,6 +369,7 @@ type
|
|||||||
function CreateCallStack: TDBGCallStack; override;
|
function CreateCallStack: TDBGCallStack; override;
|
||||||
function CreateDisassembler: TDBGDisassembler; override;
|
function CreateDisassembler: TDBGDisassembler; override;
|
||||||
function CreateWatches: TDBGWatches; override;
|
function CreateWatches: TDBGWatches; override;
|
||||||
|
function CreateThreads: TDBGThreads; override;
|
||||||
function GetSupportedCommands: TDBGCommands; override;
|
function GetSupportedCommands: TDBGCommands; override;
|
||||||
function GetTargetWidth: Byte; override;
|
function GetTargetWidth: Byte; override;
|
||||||
procedure InterruptTarget; virtual;
|
procedure InterruptTarget; virtual;
|
||||||
@ -376,6 +377,7 @@ type
|
|||||||
function RequestCommand(const ACommand: TDBGCommand; const AParams: array of const): Boolean; override;
|
function RequestCommand(const ACommand: TDBGCommand; const AParams: array of const): Boolean; override;
|
||||||
procedure ClearCommandQueue;
|
procedure ClearCommandQueue;
|
||||||
procedure DoState(const OldState: TDBGState); override;
|
procedure DoState(const OldState: TDBGState); override;
|
||||||
|
procedure DoThreadChanged;
|
||||||
property TargetPID: Integer read FTargetInfo.TargetPID;
|
property TargetPID: Integer read FTargetInfo.TargetPID;
|
||||||
property TargetPtrSize: Byte read FTargetInfo.TargetPtrSize;
|
property TargetPtrSize: Byte read FTargetInfo.TargetPtrSize;
|
||||||
property TargetFlags: TGDBMITargetFlags read FTargetInfo.TargetFlags write FTargetInfo.TargetFlags;
|
property TargetFlags: TGDBMITargetFlags read FTargetInfo.TargetFlags write FTargetInfo.TargetFlags;
|
||||||
@ -464,6 +466,7 @@ const
|
|||||||
GDCMD_PRIOR_LINE_INFO = 100; // Line info should run asap
|
GDCMD_PRIOR_LINE_INFO = 100; // Line info should run asap
|
||||||
GDCMD_PRIOR_DISASS = 30; // Run before watches
|
GDCMD_PRIOR_DISASS = 30; // Run before watches
|
||||||
GDCMD_PRIOR_USER_ACT = 10; // set/change/remove brkpoint
|
GDCMD_PRIOR_USER_ACT = 10; // set/change/remove brkpoint
|
||||||
|
GDCMD_PRIOR_THREAD = 5; // Run before watches, stack or locals
|
||||||
GDCMD_PRIOR_STACK = 2; // Run before watches
|
GDCMD_PRIOR_STACK = 2; // Run before watches
|
||||||
GDCMD_PRIOR_LOCALS = 1; // Run before watches (also registers etc)
|
GDCMD_PRIOR_LOCALS = 1; // Run before watches (also registers etc)
|
||||||
|
|
||||||
@ -957,6 +960,7 @@ type
|
|||||||
|
|
||||||
function GetCurrent: TCallStackEntry; override;
|
function GetCurrent: TCallStackEntry; override;
|
||||||
procedure SetCurrent(AValue: TCallStackEntry); override;
|
procedure SetCurrent(AValue: TCallStackEntry); override;
|
||||||
|
procedure DoThreadChanged;
|
||||||
public
|
public
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1106,6 +1110,68 @@ type
|
|||||||
|
|
||||||
{%endregion ^^^^^ Disassembler ^^^^^ }
|
{%endregion ^^^^^ Disassembler ^^^^^ }
|
||||||
|
|
||||||
|
{%region ***** Register ***** }
|
||||||
|
|
||||||
|
{ TGDBMIDebuggerCommandThreads }
|
||||||
|
|
||||||
|
TGDBMIDebuggerCommandThreads = class(TGDBMIDebuggerCommand)
|
||||||
|
private
|
||||||
|
FCurrentThreadId: Integer;
|
||||||
|
FThreads: Array of TDBGThreadEntry;
|
||||||
|
function GetThread(AnIndex: Integer): TDBGThreadEntry;
|
||||||
|
protected
|
||||||
|
function DoExecute: Boolean; override;
|
||||||
|
public
|
||||||
|
destructor Destroy; override;
|
||||||
|
//function DebugText: String; override;
|
||||||
|
function Count: Integer;
|
||||||
|
property Threads[AnIndex: Integer]: TDBGThreadEntry read GetThread;
|
||||||
|
property CurrentThreadId: Integer read FCurrentThreadId;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TGDBMIDebuggerCommandChangeThread }
|
||||||
|
|
||||||
|
TGDBMIDebuggerCommandChangeThread = class(TGDBMIDebuggerCommand)
|
||||||
|
private
|
||||||
|
FNewId: Integer;
|
||||||
|
FSuccess: Boolean;
|
||||||
|
protected
|
||||||
|
function DoExecute: Boolean; override;
|
||||||
|
public
|
||||||
|
constructor Create(AOwner: TGDBMIDebugger; ANewId: Integer);
|
||||||
|
function DebugText: String; override;
|
||||||
|
property Success: Boolean read FSuccess;
|
||||||
|
property NewId: Integer read FNewId write FNewId;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{ TGDBMIThreads }
|
||||||
|
|
||||||
|
TGDBMIThreads = class(TDBGThreads)
|
||||||
|
private
|
||||||
|
FGetThreadsCmdObj: TGDBMIDebuggerCommandThreads;
|
||||||
|
FThreadsReqState: TGDBMIEvaluationState;
|
||||||
|
|
||||||
|
FChangeThreadsCmdObj: TGDBMIDebuggerCommandChangeThread;
|
||||||
|
|
||||||
|
function GetDebugger: TGDBMIDebugger;
|
||||||
|
procedure ThreadsNeeded;
|
||||||
|
procedure CancelEvaluation;
|
||||||
|
procedure DoThreadsDestroyed(Sender: TObject);
|
||||||
|
procedure DoThreadsFinished(Sender: TObject);
|
||||||
|
procedure DoChangeThreadsDestroyed(Sender: TObject);
|
||||||
|
procedure DoChangeThreadsFinished(Sender: TObject);
|
||||||
|
protected
|
||||||
|
procedure RequestMasterData; override;
|
||||||
|
procedure ChangeCurrentThread(ANewId: Integer); override;
|
||||||
|
property Debugger: TGDBMIDebugger read GetDebugger;
|
||||||
|
public
|
||||||
|
constructor Create(const ADebugger: TDebugger);
|
||||||
|
destructor Destroy; override;
|
||||||
|
procedure DoStateChange(const AOldState: TDBGState); override;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{%endregion ^^^^^ Register ^^^^^ }
|
||||||
|
|
||||||
{%region ***** TGDBMIExpression ***** }
|
{%region ***** TGDBMIExpression ***** }
|
||||||
|
|
||||||
@ -1303,6 +1369,251 @@ begin
|
|||||||
Result := '"' + Result + '"';
|
Result := '"' + Result + '"';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TGDBMIDebuggerCommandChangeThread }
|
||||||
|
|
||||||
|
function TGDBMIDebuggerCommandChangeThread.DoExecute: Boolean;
|
||||||
|
var
|
||||||
|
R: TGDBMIExecResult;
|
||||||
|
begin
|
||||||
|
Result := True;
|
||||||
|
FSuccess := ExecuteCommand('-thread-select %d', [FNewId], R);
|
||||||
|
if FSuccess then
|
||||||
|
FSuccess := R.State <> dsError;
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TGDBMIDebuggerCommandChangeThread.Create(AOwner: TGDBMIDebugger; ANewId: Integer);
|
||||||
|
begin
|
||||||
|
inherited Create(AOwner);
|
||||||
|
FNewId := ANewId;
|
||||||
|
FSuccess := False;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TGDBMIDebuggerCommandChangeThread.DebugText: String;
|
||||||
|
begin
|
||||||
|
Result := Format('%s: NewId=%d', [ClassName, FNewId]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TGDBMIThreads }
|
||||||
|
|
||||||
|
procedure TGDBMIThreads.DoThreadsDestroyed(Sender: TObject);
|
||||||
|
begin
|
||||||
|
if FGetThreadsCmdObj = Sender
|
||||||
|
then FGetThreadsCmdObj:= nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TGDBMIThreads.DoThreadsFinished(Sender: TObject);
|
||||||
|
var
|
||||||
|
Cmd: TGDBMIDebuggerCommandThreads;
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
if Slave = nil then exit;
|
||||||
|
Cmd := TGDBMIDebuggerCommandThreads(Sender);
|
||||||
|
|
||||||
|
Slave.Clear;
|
||||||
|
for i := 0 to Cmd.Count - 1 do
|
||||||
|
Slave.Add(Cmd.Threads[i]);
|
||||||
|
|
||||||
|
Slave.CurrentThreadId := Cmd.CurrentThreadId;
|
||||||
|
Finished;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TGDBMIThreads.DoChangeThreadsDestroyed(Sender: TObject);
|
||||||
|
begin
|
||||||
|
if FChangeThreadsCmdObj = Sender
|
||||||
|
then FChangeThreadsCmdObj := nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TGDBMIThreads.DoChangeThreadsFinished(Sender: TObject);
|
||||||
|
var
|
||||||
|
Cmd: TGDBMIDebuggerCommandChangeThread;
|
||||||
|
begin
|
||||||
|
if Slave = nil then exit;
|
||||||
|
Cmd := TGDBMIDebuggerCommandChangeThread(Sender);
|
||||||
|
|
||||||
|
if not Cmd.Success then begin
|
||||||
|
Changed; // invalidate slave
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Slave.CurrentThreadId := Cmd.NewId;
|
||||||
|
Finished;
|
||||||
|
Debugger.DoThreadChanged;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TGDBMIThreads.GetDebugger: TGDBMIDebugger;
|
||||||
|
begin
|
||||||
|
Result := TGDBMIDebugger(inherited Debugger);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TGDBMIThreads.ThreadsNeeded;
|
||||||
|
var
|
||||||
|
ForceQueue: Boolean;
|
||||||
|
begin
|
||||||
|
if FThreadsReqState in [esValid, esRequested] then Exit;
|
||||||
|
if Debugger = nil then Exit;
|
||||||
|
|
||||||
|
if (Debugger.State = dsPause)
|
||||||
|
then begin
|
||||||
|
FThreadsReqState := esRequested;
|
||||||
|
FGetThreadsCmdObj := TGDBMIDebuggerCommandThreads.Create(Debugger);
|
||||||
|
FGetThreadsCmdObj.OnExecuted := @DoThreadsFinished;
|
||||||
|
FGetThreadsCmdObj.OnDestroy := @DoThreadsDestroyed;
|
||||||
|
FGetThreadsCmdObj.Properties := [dcpCancelOnRun];
|
||||||
|
FGetThreadsCmdObj.Priority := GDCMD_PRIOR_THREAD;
|
||||||
|
// If a ExecCmd is running, then defer exec until the exec cmd is done
|
||||||
|
ForceQueue := (TGDBMIDebugger(Debugger).FCurrentCommand <> nil)
|
||||||
|
and (TGDBMIDebugger(Debugger).FCurrentCommand is TGDBMIDebuggerCommandExecute)
|
||||||
|
and (not TGDBMIDebuggerCommandExecute(TGDBMIDebugger(Debugger).FCurrentCommand).NextExecQueued);
|
||||||
|
TGDBMIDebugger(Debugger).QueueCommand(FGetThreadsCmdObj, ForceQueue);
|
||||||
|
(* DoEvaluationFinished may be called immediately at this point *)
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TGDBMIThreads.CancelEvaluation;
|
||||||
|
begin
|
||||||
|
FThreadsReqState := esInvalid;
|
||||||
|
if FGetThreadsCmdObj <> nil
|
||||||
|
then begin
|
||||||
|
FGetThreadsCmdObj.OnExecuted := nil;
|
||||||
|
FGetThreadsCmdObj.OnDestroy := nil;
|
||||||
|
FGetThreadsCmdObj.Cancel;
|
||||||
|
end;
|
||||||
|
FGetThreadsCmdObj := nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TGDBMIThreads.Create(const ADebugger: TDebugger);
|
||||||
|
begin
|
||||||
|
inherited;
|
||||||
|
FThreadsReqState := esInvalid;
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TGDBMIThreads.Destroy;
|
||||||
|
begin
|
||||||
|
CancelEvaluation;
|
||||||
|
inherited Destroy;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TGDBMIThreads.DoStateChange(const AOldState: TDBGState);
|
||||||
|
begin
|
||||||
|
if (Debugger = nil) or (Slave = nil) then Exit;
|
||||||
|
|
||||||
|
if Debugger.State in [dsPause, dsStop]
|
||||||
|
then begin
|
||||||
|
CancelEvaluation;
|
||||||
|
FThreadsReqState := esInvalid;
|
||||||
|
Changed;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TGDBMIThreads.RequestMasterData;
|
||||||
|
begin
|
||||||
|
ThreadsNeeded;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TGDBMIThreads.ChangeCurrentThread(ANewId: Integer);
|
||||||
|
var
|
||||||
|
ForceQueue: Boolean;
|
||||||
|
begin
|
||||||
|
if Debugger = nil then Exit;
|
||||||
|
if (Debugger.State <> dsPause) then exit;
|
||||||
|
|
||||||
|
if FChangeThreadsCmdObj <> nil then begin
|
||||||
|
if FChangeThreadsCmdObj.State = dcsQueued then
|
||||||
|
FChangeThreadsCmdObj.NewId := ANewId;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
FChangeThreadsCmdObj := TGDBMIDebuggerCommandChangeThread.Create(Debugger, ANewId);
|
||||||
|
FChangeThreadsCmdObj.OnExecuted := @DoChangeThreadsFinished;
|
||||||
|
FChangeThreadsCmdObj.OnDestroy := @DoChangeThreadsDestroyed;
|
||||||
|
FChangeThreadsCmdObj.Properties := [dcpCancelOnRun];
|
||||||
|
FChangeThreadsCmdObj.Priority := GDCMD_PRIOR_USER_ACT;
|
||||||
|
// If a ExecCmd is running, then defer exec until the exec cmd is done
|
||||||
|
ForceQueue := (TGDBMIDebugger(Debugger).FCurrentCommand <> nil)
|
||||||
|
and (TGDBMIDebugger(Debugger).FCurrentCommand is TGDBMIDebuggerCommandExecute)
|
||||||
|
and (not TGDBMIDebuggerCommandExecute(TGDBMIDebugger(Debugger).FCurrentCommand).NextExecQueued);
|
||||||
|
TGDBMIDebugger(Debugger).QueueCommand(FChangeThreadsCmdObj, ForceQueue);
|
||||||
|
(* DoEvaluationFinished may be called immediately at this point *)
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TGDBMIDebuggerCommandThreads }
|
||||||
|
|
||||||
|
function TGDBMIDebuggerCommandThreads.GetThread(AnIndex: Integer): TDBGThreadEntry;
|
||||||
|
begin
|
||||||
|
Result := FThreads[AnIndex];
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TGDBMIDebuggerCommandThreads.DoExecute: Boolean;
|
||||||
|
var
|
||||||
|
R: TGDBMIExecResult;
|
||||||
|
List, EList, ArgList: TGDBMINameValueList;
|
||||||
|
i, j: Integer;
|
||||||
|
line, ThrId: Integer;
|
||||||
|
func, filename, fullname: String;
|
||||||
|
ThrName, ThrState: string;
|
||||||
|
addr: TDBGPtr;
|
||||||
|
Arguments: TStringList;
|
||||||
|
begin
|
||||||
|
Result := True;
|
||||||
|
|
||||||
|
ExecuteCommand('-thread-info', R);
|
||||||
|
List := TGDBMINameValueList.Create(R);
|
||||||
|
EList := TGDBMINameValueList.Create;
|
||||||
|
ArgList := TGDBMINameValueList.Create;
|
||||||
|
|
||||||
|
FCurrentThreadId := StrToIntDef(List.Values['current-thread-id'], -1);
|
||||||
|
|
||||||
|
List.SetPath('threads');
|
||||||
|
SetLength(FThreads, List.Count);
|
||||||
|
for i := 0 to List.Count - 1 do begin
|
||||||
|
EList.Init(List.Items[i]^.Name);
|
||||||
|
ThrId := StrToIntDef(EList.Values['id'], -2);
|
||||||
|
ThrName := EList.Values['target-id'];
|
||||||
|
ThrState := EList.Values['state'];
|
||||||
|
EList.SetPath('frame');
|
||||||
|
addr := StrToQWordDef(EList.Values['addr'], 0);
|
||||||
|
func := EList.Values['func'];
|
||||||
|
filename := ConvertGdbPathAndFile(EList.Values['file']);
|
||||||
|
fullname := ConvertGdbPathAndFile(EList.Values['fullname']);
|
||||||
|
line := StrToIntDef(EList.Values['line'], 0);
|
||||||
|
|
||||||
|
EList.SetPath('args');
|
||||||
|
Arguments := TStringList.Create;
|
||||||
|
for j := 0 to EList.Count - 1 do begin
|
||||||
|
ArgList.Init(EList.Items[j]^.Name);
|
||||||
|
Arguments.Add(ArgList.Values['name'] + '=' + DeleteEscapeChars(ArgList.Values['value']));
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
FThreads[i] := TDBGThreadEntry.Create(
|
||||||
|
0, addr,
|
||||||
|
Arguments,
|
||||||
|
func, filename, fullname, line,
|
||||||
|
ThrId,ThrName, ThrState
|
||||||
|
);
|
||||||
|
|
||||||
|
Arguments.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
FreeAndNil(ArgList);
|
||||||
|
FreeAndNil(EList);
|
||||||
|
FreeAndNil(List);
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TGDBMIDebuggerCommandThreads.Destroy;
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
for i := 0 to length(FThreads) - 1 do FreeAndNil(FThreads[i]);
|
||||||
|
FThreads := nil;
|
||||||
|
inherited Destroy;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TGDBMIDebuggerCommandThreads.Count: Integer;
|
||||||
|
begin
|
||||||
|
Result := length(FThreads);
|
||||||
|
end;
|
||||||
|
|
||||||
{ TGDBMIDebuggerCommandRegisterModified }
|
{ TGDBMIDebuggerCommandRegisterModified }
|
||||||
|
|
||||||
function TGDBMIDebuggerCommandRegisterModified.DoExecute: Boolean;
|
function TGDBMIDebuggerCommandRegisterModified.DoExecute: Boolean;
|
||||||
@ -4485,6 +4796,11 @@ begin
|
|||||||
Result := TGDBMIWatches.Create(Self, TGDBMIWatch);
|
Result := TGDBMIWatches.Create(Self, TGDBMIWatch);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TGDBMIDebugger.CreateThreads: TDBGThreads;
|
||||||
|
begin
|
||||||
|
Result := TGDBMIThreads.Create(Self);
|
||||||
|
end;
|
||||||
|
|
||||||
destructor TGDBMIDebugger.Destroy;
|
destructor TGDBMIDebugger.Destroy;
|
||||||
begin
|
begin
|
||||||
LockRelease;
|
LockRelease;
|
||||||
@ -4569,6 +4885,14 @@ begin
|
|||||||
inherited DoState(OldState);
|
inherited DoState(OldState);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TGDBMIDebugger.DoThreadChanged;
|
||||||
|
begin
|
||||||
|
TGDBMICallstack(CallStack).DoThreadChanged;
|
||||||
|
TGDBMILocals(Locals).Changed;
|
||||||
|
TGDBMIRegisters(Registers).Changed;
|
||||||
|
TGDBMIWatches(Watches).Changed;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TGDBMIDebugger.DoRelease;
|
procedure TGDBMIDebugger.DoRelease;
|
||||||
begin
|
begin
|
||||||
SetState(dsDestroying);
|
SetState(dsDestroying);
|
||||||
@ -7106,6 +7430,12 @@ begin
|
|||||||
TGDBMIDebugger(Debugger).CallStackSetCurrent(AValue.Index);
|
TGDBMIDebugger(Debugger).CallStackSetCurrent(AValue.Index);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TGDBMICallStack.DoThreadChanged;
|
||||||
|
begin
|
||||||
|
Clear;
|
||||||
|
Changed;
|
||||||
|
end;
|
||||||
|
|
||||||
{ =========================================================================== }
|
{ =========================================================================== }
|
||||||
{ TGDBMIExpression }
|
{ TGDBMIExpression }
|
||||||
{ =========================================================================== }
|
{ =========================================================================== }
|
||||||
|
65
debugger/threaddlg.lfm
Normal file
65
debugger/threaddlg.lfm
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
inherited ThreadsDlg: TThreadsDlg
|
||||||
|
Left = 345
|
||||||
|
Top = 428
|
||||||
|
Width = 774
|
||||||
|
BorderStyle = bsSizeToolWin
|
||||||
|
Caption = 'Threads'
|
||||||
|
ClientWidth = 774
|
||||||
|
object lvThreads: TListView[0]
|
||||||
|
Left = 0
|
||||||
|
Height = 214
|
||||||
|
Top = 26
|
||||||
|
Width = 774
|
||||||
|
Align = alClient
|
||||||
|
Columns = <
|
||||||
|
item
|
||||||
|
Width = 20
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Caption = 'Id'
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Caption = 'TargetId'
|
||||||
|
Width = 100
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Caption = 'State'
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Caption = 'Source'
|
||||||
|
Width = 150
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Caption = 'Line'
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Caption = 'Function'
|
||||||
|
Width = 300
|
||||||
|
end>
|
||||||
|
RowSelect = True
|
||||||
|
TabOrder = 0
|
||||||
|
ViewStyle = vsReport
|
||||||
|
OnDblClick = lvThreadsDblClick
|
||||||
|
end
|
||||||
|
object ToolBar1: TToolBar[1]
|
||||||
|
Left = 0
|
||||||
|
Height = 26
|
||||||
|
Top = 0
|
||||||
|
Width = 774
|
||||||
|
Caption = 'ToolBar1'
|
||||||
|
ShowCaptions = True
|
||||||
|
TabOrder = 1
|
||||||
|
object tbCurrent: TToolButton
|
||||||
|
Left = 1
|
||||||
|
Top = 2
|
||||||
|
Caption = 'tbCurrent'
|
||||||
|
OnClick = tbCurrentClick
|
||||||
|
end
|
||||||
|
object tbGoto: TToolButton
|
||||||
|
Left = 60
|
||||||
|
Top = 2
|
||||||
|
Caption = 'tbGoto'
|
||||||
|
OnClick = lvThreadsDblClick
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
164
debugger/threaddlg.pp
Normal file
164
debugger/threaddlg.pp
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
unit ThreadDlg;
|
||||||
|
|
||||||
|
{$mode objfpc}{$H+}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ComCtrls,
|
||||||
|
Debugger, DebuggerDlg, LazarusIDEStrConsts, BaseDebugManager, MainBase;
|
||||||
|
|
||||||
|
type
|
||||||
|
|
||||||
|
{ TThreadsDlg }
|
||||||
|
|
||||||
|
TThreadsDlg = class(TDebuggerDlg)
|
||||||
|
lvThreads: TListView;
|
||||||
|
ToolBar1: TToolBar;
|
||||||
|
tbCurrent: TToolButton;
|
||||||
|
tbGoto: TToolButton;
|
||||||
|
procedure lvThreadsDblClick(Sender: TObject);
|
||||||
|
procedure tbCurrentClick(Sender: TObject);
|
||||||
|
procedure ThreadsChanged(Sender: TObject);
|
||||||
|
private
|
||||||
|
{ private declarations }
|
||||||
|
FThreadNotification: TIDEThreadsNotification;
|
||||||
|
FThreads: TIDEThreads;
|
||||||
|
procedure SetThreads(const AValue: TIDEThreads);
|
||||||
|
procedure JumpToSource;
|
||||||
|
public
|
||||||
|
{ public declarations }
|
||||||
|
constructor Create(TheOwner: TComponent); override;
|
||||||
|
destructor Destroy; override;
|
||||||
|
property Threads: TIDEThreads read FThreads write SetThreads;
|
||||||
|
end;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
{$R *.lfm}
|
||||||
|
|
||||||
|
{ TThreadsDlg }
|
||||||
|
|
||||||
|
procedure TThreadsDlg.ThreadsChanged(Sender: TObject);
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
s: String;
|
||||||
|
Item: TListItem;
|
||||||
|
begin
|
||||||
|
if FThreads = nil then begin
|
||||||
|
lvThreads.Clear;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
lvThreads.Items.Count := FThreads.Count;
|
||||||
|
|
||||||
|
i := FThreads.Count;
|
||||||
|
while lvThreads.Items.Count > i do lvThreads.Items.Delete(i);
|
||||||
|
while lvThreads.Items.Count < i do begin
|
||||||
|
Item := lvThreads.Items.Add;
|
||||||
|
Item.SubItems.add('');
|
||||||
|
Item.SubItems.add('');
|
||||||
|
Item.SubItems.add('');
|
||||||
|
Item.SubItems.add('');
|
||||||
|
Item.SubItems.add('');
|
||||||
|
Item.SubItems.add('');
|
||||||
|
end;
|
||||||
|
|
||||||
|
for i := 0 to FThreads.Count - 1 do begin
|
||||||
|
if Threads[i].ThreadId = Threads.CurrentThreadId
|
||||||
|
then lvThreads.Items[i].Caption := '*'
|
||||||
|
else lvThreads.Items[i].Caption := '';
|
||||||
|
lvThreads.Items[i].SubItems[0] := IntToStr(Threads[i].ThreadId);
|
||||||
|
lvThreads.Items[i].SubItems[1] := Threads[i].ThreadName;
|
||||||
|
lvThreads.Items[i].SubItems[2] := Threads[i].ThreadState;
|
||||||
|
s := Threads[i].Source;
|
||||||
|
if s = '' then s := ';' + IntToHex(Threads[i].Address, 8);
|
||||||
|
lvThreads.Items[i].SubItems[3] := s;
|
||||||
|
lvThreads.Items[i].SubItems[4] := IntToStr(Threads[i].Line);
|
||||||
|
lvThreads.Items[i].SubItems[5] := Threads[i].GetFunctionWithArg;
|
||||||
|
lvThreads.Items[i].Data := Threads[i];
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TThreadsDlg.tbCurrentClick(Sender: TObject);
|
||||||
|
var
|
||||||
|
Item: TListItem;
|
||||||
|
id: LongInt;
|
||||||
|
begin
|
||||||
|
Item := lvThreads.Selected;
|
||||||
|
if Item = nil then exit;
|
||||||
|
id := StrToIntDef(Item.SubItems[0], -1);
|
||||||
|
if id < 0 then exit;
|
||||||
|
FThreads.ChangeCurrentThread(id);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TThreadsDlg.lvThreadsDblClick(Sender: TObject);
|
||||||
|
begin
|
||||||
|
JumpToSource;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TThreadsDlg.SetThreads(const AValue: TIDEThreads);
|
||||||
|
begin
|
||||||
|
if FThreads = AValue then exit;
|
||||||
|
if FThreads <> nil then FThreads.RemoveNotification(FThreadNotification);
|
||||||
|
FThreads := AValue;
|
||||||
|
if FThreads <> nil then FThreads.AddNotification(FThreadNotification);
|
||||||
|
ThreadsChanged(FThreads);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TThreadsDlg.JumpToSource;
|
||||||
|
var
|
||||||
|
Entry: TDBGThreadEntry;
|
||||||
|
Filename: String;
|
||||||
|
Item: TListItem;
|
||||||
|
begin
|
||||||
|
Item := lvThreads.Selected;
|
||||||
|
if Item = nil then exit;
|
||||||
|
Entry := TDBGThreadEntry(Item.Data);
|
||||||
|
if Entry = nil then Exit;
|
||||||
|
|
||||||
|
// avoid any process-messages, so this proc can not be re-entered (avoid opening one files many times)
|
||||||
|
DebugBoss.LockCommandProcessing;
|
||||||
|
try
|
||||||
|
// check the full name first
|
||||||
|
Filename := Entry.FullFileName;
|
||||||
|
if (Filename = '') or not DebugBoss.GetFullFilename(Filename, False) then
|
||||||
|
begin
|
||||||
|
// if fails the check the short file name
|
||||||
|
Filename := Entry.Source;
|
||||||
|
if (FileName = '') or not DebugBoss.GetFullFilename(Filename, True) then
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
MainIDE.DoJumpToSourcePosition(Filename, 0, Entry.Line, 0, True, True);
|
||||||
|
finally
|
||||||
|
DebugBoss.UnLockCommandProcessing;
|
||||||
|
end;end;
|
||||||
|
|
||||||
|
constructor TThreadsDlg.Create(TheOwner: TComponent);
|
||||||
|
begin
|
||||||
|
inherited Create(TheOwner);
|
||||||
|
Caption:= lisThreads;
|
||||||
|
lvThreads.Column[1].Caption := lisThreadsID;
|
||||||
|
lvThreads.Column[2].Caption := lisThreadsName;
|
||||||
|
lvThreads.Column[2].Caption := lisThreadsState;
|
||||||
|
lvThreads.Column[3].Caption := lisThreadsSrc;
|
||||||
|
lvThreads.Column[4].Caption := lisThreadsLine;
|
||||||
|
lvThreads.Column[5].Caption := lisThreadsFunc;
|
||||||
|
tbCurrent.Caption := lisThreadsCurrent;
|
||||||
|
tbGoto.Caption := lisThreadsGoto;
|
||||||
|
|
||||||
|
FThreadNotification := TIDEThreadsNotification.Create;
|
||||||
|
FThreadNotification.AddReference;
|
||||||
|
FThreadNotification.OnChange := @ThreadsChanged;
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TThreadsDlg.Destroy;
|
||||||
|
begin
|
||||||
|
SetThreads(nil);
|
||||||
|
FThreadNotification.OnChange := nil;
|
||||||
|
FThreadNotification.ReleaseReference;
|
||||||
|
inherited Destroy;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
@ -55,7 +55,8 @@ type
|
|||||||
ddtRegisters,
|
ddtRegisters,
|
||||||
ddtAssembler,
|
ddtAssembler,
|
||||||
ddtInspect,
|
ddtInspect,
|
||||||
ddtPseudoTerminal
|
ddtPseudoTerminal,
|
||||||
|
ddtThreads
|
||||||
);
|
);
|
||||||
|
|
||||||
{ TBaseDebugManager }
|
{ TBaseDebugManager }
|
||||||
@ -91,6 +92,7 @@ type
|
|||||||
FLocals: TIDELocals;
|
FLocals: TIDELocals;
|
||||||
FLineInfo: TIDELineInfo;
|
FLineInfo: TIDELineInfo;
|
||||||
FWatches: TIDEWatches;
|
FWatches: TIDEWatches;
|
||||||
|
FThreads: TIDEThreads;
|
||||||
FRegisters: TIDERegisters;
|
FRegisters: TIDERegisters;
|
||||||
FManagerStates: TDebugManagerStates;
|
FManagerStates: TDebugManagerStates;
|
||||||
function FindDebuggerClass(const Astring: String): TDebuggerClass;
|
function FindDebuggerClass(const Astring: String): TDebuggerClass;
|
||||||
@ -176,6 +178,7 @@ type
|
|||||||
property Registers: TIDERegisters read FRegisters;
|
property Registers: TIDERegisters read FRegisters;
|
||||||
property Signals: TIDESignals read FSignals; // A list of actions for signals we know of
|
property Signals: TIDESignals read FSignals; // A list of actions for signals we know of
|
||||||
property Watches: TIDEWatches read FWatches;
|
property Watches: TIDEWatches read FWatches;
|
||||||
|
property Threads: TIDEThreads read FThreads;
|
||||||
{$IFDEF DBG_WITH_DEBUGGER_DEBUG}
|
{$IFDEF DBG_WITH_DEBUGGER_DEBUG}
|
||||||
property Debugger: TDebugger read GetDebugger;
|
property Debugger: TDebugger read GetDebugger;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
@ -56,7 +56,7 @@ uses
|
|||||||
SourceMarks,
|
SourceMarks,
|
||||||
DebuggerDlg, Watchesdlg, BreakPointsdlg, BreakPropertyDlg, LocalsDlg, WatchPropertyDlg,
|
DebuggerDlg, Watchesdlg, BreakPointsdlg, BreakPropertyDlg, LocalsDlg, WatchPropertyDlg,
|
||||||
CallStackDlg, EvaluateDlg, RegistersDlg, AssemblerDlg, DebugOutputForm, ExceptionDlg,
|
CallStackDlg, EvaluateDlg, RegistersDlg, AssemblerDlg, DebugOutputForm, ExceptionDlg,
|
||||||
InspectDlg, DebugEventsForm, PseudoTerminalDlg, FeedbackDlg,
|
InspectDlg, DebugEventsForm, PseudoTerminalDlg, FeedbackDlg, ThreadDlg,
|
||||||
GDBMIDebugger, SSHGDBMIDebugger, ProcessDebugger,
|
GDBMIDebugger, SSHGDBMIDebugger, ProcessDebugger,
|
||||||
BaseDebugManager;
|
BaseDebugManager;
|
||||||
|
|
||||||
@ -127,6 +127,7 @@ type
|
|||||||
procedure InitDebugEventsDlg;
|
procedure InitDebugEventsDlg;
|
||||||
procedure InitBreakPointDlg;
|
procedure InitBreakPointDlg;
|
||||||
procedure InitWatchesDlg;
|
procedure InitWatchesDlg;
|
||||||
|
procedure InitThreadsDlg;
|
||||||
procedure InitPseudoTerminal;
|
procedure InitPseudoTerminal;
|
||||||
procedure InitLocalsDlg;
|
procedure InitLocalsDlg;
|
||||||
procedure InitCallStackDlg;
|
procedure InitCallStackDlg;
|
||||||
@ -218,7 +219,7 @@ const
|
|||||||
DebugDlgIDEWindow: array[TDebugDialogType] of TNonModalIDEWindow = (
|
DebugDlgIDEWindow: array[TDebugDialogType] of TNonModalIDEWindow = (
|
||||||
nmiwDbgOutput, nmiwDbgEvents, nmiwBreakPoints, nmiwWatches, nmiwLocals,
|
nmiwDbgOutput, nmiwDbgEvents, nmiwBreakPoints, nmiwWatches, nmiwLocals,
|
||||||
nmiwCallStack, nmiwEvaluate, nmiwRegisters, nmiwAssembler, nmiwInspect,
|
nmiwCallStack, nmiwEvaluate, nmiwRegisters, nmiwAssembler, nmiwInspect,
|
||||||
nmiwPseudoTerminal
|
nmiwPseudoTerminal, nmiwThreads
|
||||||
);
|
);
|
||||||
|
|
||||||
type
|
type
|
||||||
@ -1556,6 +1557,7 @@ begin
|
|||||||
ecEvaluate : ViewDebugDialog(ddtEvaluate);
|
ecEvaluate : ViewDebugDialog(ddtEvaluate);
|
||||||
ecInspect : ViewDebugDialog(ddtInspect);
|
ecInspect : ViewDebugDialog(ddtInspect);
|
||||||
ecViewPseudoTerminal: ViewDebugDialog(ddtPseudoTerminal);
|
ecViewPseudoTerminal: ViewDebugDialog(ddtPseudoTerminal);
|
||||||
|
ecViewThreads : ViewDebugDialog(ddtThreads);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -1957,7 +1959,7 @@ const
|
|||||||
DEBUGDIALOGCLASS: array[TDebugDialogType] of TDebuggerDlgClass = (
|
DEBUGDIALOGCLASS: array[TDebugDialogType] of TDebuggerDlgClass = (
|
||||||
TDbgOutputForm, TDbgEventsForm, TBreakPointsDlg, TWatchesDlg, TLocalsDlg,
|
TDbgOutputForm, TDbgEventsForm, TBreakPointsDlg, TWatchesDlg, TLocalsDlg,
|
||||||
TCallStackDlg, TEvaluateDlg, TRegistersDlg, TAssemblerDlg, TIDEInspectDlg,
|
TCallStackDlg, TEvaluateDlg, TRegistersDlg, TAssemblerDlg, TIDEInspectDlg,
|
||||||
TPseudoConsoleDlg
|
TPseudoConsoleDlg, TThreadsDlg
|
||||||
);
|
);
|
||||||
var
|
var
|
||||||
CurDialog: TDebuggerDlg;
|
CurDialog: TDebuggerDlg;
|
||||||
@ -1986,6 +1988,7 @@ begin
|
|||||||
ddtAssembler: InitAssemblerDlg;
|
ddtAssembler: InitAssemblerDlg;
|
||||||
ddtInspect: InitInspectDlg;
|
ddtInspect: InitInspectDlg;
|
||||||
ddtPseudoTerminal: InitPseudoTerminal;
|
ddtPseudoTerminal: InitPseudoTerminal;
|
||||||
|
ddtThreads: InitThreadsDlg;
|
||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
@ -2059,6 +2062,14 @@ begin
|
|||||||
TheDialog.Watches := FWatches;
|
TheDialog.Watches := FWatches;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TDebugManager.InitThreadsDlg;
|
||||||
|
var
|
||||||
|
TheDialog: TThreadsDlg;
|
||||||
|
begin
|
||||||
|
TheDialog := TThreadsDlg(FDialogs[ddtThreads]);
|
||||||
|
TheDialog.Threads := FThreads;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TDebugManager.InitPseudoTerminal;
|
procedure TDebugManager.InitPseudoTerminal;
|
||||||
//var
|
//var
|
||||||
// TheDialog: TPseudoConsoleDlg;
|
// TheDialog: TPseudoConsoleDlg;
|
||||||
@ -2139,6 +2150,7 @@ begin
|
|||||||
FBreakPoints := TManagedBreakPoints.Create(Self);
|
FBreakPoints := TManagedBreakPoints.Create(Self);
|
||||||
FBreakPointGroups := TIDEBreakPointGroups.Create;
|
FBreakPointGroups := TIDEBreakPointGroups.Create;
|
||||||
FWatches := TManagedWatches.Create(Self);
|
FWatches := TManagedWatches.Create(Self);
|
||||||
|
FThreads := TIDEThreads.Create;
|
||||||
FExceptions := TManagedExceptions.Create(Self);
|
FExceptions := TManagedExceptions.Create(Self);
|
||||||
FSignals := TManagedSignals.Create(Self);
|
FSignals := TManagedSignals.Create(Self);
|
||||||
FLocals := TManagedLocals.Create;
|
FLocals := TManagedLocals.Create;
|
||||||
@ -2176,6 +2188,7 @@ begin
|
|||||||
SetDebugger(nil);
|
SetDebugger(nil);
|
||||||
|
|
||||||
FreeAndNil(FWatches);
|
FreeAndNil(FWatches);
|
||||||
|
FreeAndNil(FThreads);
|
||||||
FreeAndNil(FBreakPoints);
|
FreeAndNil(FBreakPoints);
|
||||||
FreeAndNil(FBreakPointGroups);
|
FreeAndNil(FBreakPointGroups);
|
||||||
FreeAndNil(FCallStack);
|
FreeAndNil(FCallStack);
|
||||||
@ -2199,6 +2212,7 @@ begin
|
|||||||
FBreakPoints.Clear;
|
FBreakPoints.Clear;
|
||||||
FBreakPointGroups.Clear;
|
FBreakPointGroups.Clear;
|
||||||
FWatches.Clear;
|
FWatches.Clear;
|
||||||
|
FThreads.Clear;
|
||||||
FExceptions.Reset;
|
FExceptions.Reset;
|
||||||
FSignals.Reset;
|
FSignals.Reset;
|
||||||
FUserSourceFiles.Clear;
|
FUserSourceFiles.Clear;
|
||||||
@ -2220,6 +2234,8 @@ begin
|
|||||||
itmViewRegisters.Tag := Ord(ddtRegisters);
|
itmViewRegisters.Tag := Ord(ddtRegisters);
|
||||||
itmViewCallStack.OnClick := @mnuViewDebugDialogClick;
|
itmViewCallStack.OnClick := @mnuViewDebugDialogClick;
|
||||||
itmViewCallStack.Tag := Ord(ddtCallStack);
|
itmViewCallStack.Tag := Ord(ddtCallStack);
|
||||||
|
itmViewThreads.OnClick := @mnuViewDebugDialogClick;
|
||||||
|
itmViewThreads.Tag := Ord(ddtThreads);
|
||||||
itmViewAssembler.OnClick := @mnuViewDebugDialogClick;
|
itmViewAssembler.OnClick := @mnuViewDebugDialogClick;
|
||||||
itmViewAssembler.Tag := Ord(ddtAssembler);
|
itmViewAssembler.Tag := Ord(ddtAssembler);
|
||||||
itmViewDebugOutput.OnClick := @mnuViewDebugDialogClick;
|
itmViewDebugOutput.OnClick := @mnuViewDebugDialogClick;
|
||||||
@ -2874,6 +2890,7 @@ begin
|
|||||||
ecToggleDebugEvents: ViewDebugDialog(ddtEvents);
|
ecToggleDebugEvents: ViewDebugDialog(ddtEvents);
|
||||||
ecToggleLocals: ViewDebugDialog(ddtLocals);
|
ecToggleLocals: ViewDebugDialog(ddtLocals);
|
||||||
ecViewPseudoTerminal: ViewDebugDialog(ddtPseudoTerminal);
|
ecViewPseudoTerminal: ViewDebugDialog(ddtPseudoTerminal);
|
||||||
|
ecViewThreads: ViewDebugDialog(ddtThreads);
|
||||||
else
|
else
|
||||||
Handled := False;
|
Handled := False;
|
||||||
end;
|
end;
|
||||||
@ -3140,6 +3157,7 @@ begin
|
|||||||
then begin
|
then begin
|
||||||
TManagedBreakpoints(FBreakpoints).Master := nil;
|
TManagedBreakpoints(FBreakpoints).Master := nil;
|
||||||
TManagedWatches(FWatches).Master := nil;
|
TManagedWatches(FWatches).Master := nil;
|
||||||
|
FThreads.Master := nil;
|
||||||
TManagedLocals(FLocals).Master := nil;
|
TManagedLocals(FLocals).Master := nil;
|
||||||
TManagedLineInfo(FLineInfo).Master := nil;
|
TManagedLineInfo(FLineInfo).Master := nil;
|
||||||
TManagedCallStack(FCallStack).Master := nil;
|
TManagedCallStack(FCallStack).Master := nil;
|
||||||
@ -3151,6 +3169,7 @@ begin
|
|||||||
else begin
|
else begin
|
||||||
TManagedBreakpoints(FBreakpoints).Master := FDebugger.BreakPoints;
|
TManagedBreakpoints(FBreakpoints).Master := FDebugger.BreakPoints;
|
||||||
TManagedWatches(FWatches).Master := FDebugger.Watches;
|
TManagedWatches(FWatches).Master := FDebugger.Watches;
|
||||||
|
FThreads.Master := FDebugger.Threads;
|
||||||
TManagedLocals(FLocals).Master := FDebugger.Locals;
|
TManagedLocals(FLocals).Master := FDebugger.Locals;
|
||||||
TManagedLineInfo(FLineInfo).Master := FDebugger.LineInfo;
|
TManagedLineInfo(FLineInfo).Master := FDebugger.LineInfo;
|
||||||
TManagedCallStack(FCallStack).Master := FDebugger.CallStack;
|
TManagedCallStack(FCallStack).Master := FDebugger.CallStack;
|
||||||
|
@ -94,6 +94,7 @@ type
|
|||||||
nmiwAssembler,
|
nmiwAssembler,
|
||||||
nmiwInspect,
|
nmiwInspect,
|
||||||
nmiwPseudoTerminal,
|
nmiwPseudoTerminal,
|
||||||
|
nmiwThreads,
|
||||||
// extra
|
// extra
|
||||||
nmiwSearchResultsViewName,
|
nmiwSearchResultsViewName,
|
||||||
nmiwAnchorEditor,
|
nmiwAnchorEditor,
|
||||||
@ -140,6 +141,7 @@ const
|
|||||||
'Assembler',
|
'Assembler',
|
||||||
'Inspect',
|
'Inspect',
|
||||||
'PseudoTerminal',
|
'PseudoTerminal',
|
||||||
|
'Threads',
|
||||||
// extra
|
// extra
|
||||||
'SearchResults',
|
'SearchResults',
|
||||||
'AnchorEditor',
|
'AnchorEditor',
|
||||||
|
@ -513,6 +513,7 @@ begin
|
|||||||
ecToggleBreakPoints: SetResult(VK_B,[ssCtrl,ssAlt],VK_UNKNOWN,[]);
|
ecToggleBreakPoints: SetResult(VK_B,[ssCtrl,ssAlt],VK_UNKNOWN,[]);
|
||||||
ecToggleLocals: SetResult(VK_L,[ssCtrl,ssAlt],VK_UNKNOWN,[]);
|
ecToggleLocals: SetResult(VK_L,[ssCtrl,ssAlt],VK_UNKNOWN,[]);
|
||||||
ecViewPseudoTerminal: if HasConsoleSupport then SetResult(VK_T,[ssCtrl,ssAlt],VK_UNKNOWN,[]);
|
ecViewPseudoTerminal: if HasConsoleSupport then SetResult(VK_T,[ssCtrl,ssAlt],VK_UNKNOWN,[]);
|
||||||
|
ecViewThreads: SetResult(VK_T,[ssCtrl,ssAlt],VK_UNKNOWN,[]);
|
||||||
ecToggleCallStack: SetResult(VK_S,[ssCtrl,ssAlt],VK_UNKNOWN,[]);
|
ecToggleCallStack: SetResult(VK_S,[ssCtrl,ssAlt],VK_UNKNOWN,[]);
|
||||||
ecToggleRegisters: SetResult(VK_R,[ssCtrl,ssAlt],VK_UNKNOWN,[]);
|
ecToggleRegisters: SetResult(VK_R,[ssCtrl,ssAlt],VK_UNKNOWN,[]);
|
||||||
ecToggleAssembler: SetResult(VK_D,[ssCtrl,ssAlt],VK_UNKNOWN,[]);
|
ecToggleAssembler: SetResult(VK_D,[ssCtrl,ssAlt],VK_UNKNOWN,[]);
|
||||||
@ -1573,6 +1574,7 @@ begin
|
|||||||
ecToggleBreakPoints: SetResult(VK_B,[ssCtrl,ssAlt],VK_UNKNOWN,[]);
|
ecToggleBreakPoints: SetResult(VK_B,[ssCtrl,ssAlt],VK_UNKNOWN,[]);
|
||||||
ecToggleLocals: SetResult(VK_L,[ssCtrl,ssAlt],VK_UNKNOWN,[]);
|
ecToggleLocals: SetResult(VK_L,[ssCtrl,ssAlt],VK_UNKNOWN,[]);
|
||||||
ecViewPseudoTerminal: if HasConsoleSupport then SetResult(VK_T,[ssCtrl,ssAlt],VK_UNKNOWN,[]);
|
ecViewPseudoTerminal: if HasConsoleSupport then SetResult(VK_T,[ssCtrl,ssAlt],VK_UNKNOWN,[]);
|
||||||
|
ecViewThreads: SetResult(VK_T,[ssCtrl,ssAlt],VK_UNKNOWN,[]);
|
||||||
ecToggleCallStack: SetResult(VK_S,[ssCtrl,ssAlt],VK_UNKNOWN,[]);
|
ecToggleCallStack: SetResult(VK_S,[ssCtrl,ssAlt],VK_UNKNOWN,[]);
|
||||||
ecToggleRegisters: SetResult(VK_R,[ssCtrl,ssAlt],VK_UNKNOWN,[]);
|
ecToggleRegisters: SetResult(VK_R,[ssCtrl,ssAlt],VK_UNKNOWN,[]);
|
||||||
ecToggleAssembler: SetResult(VK_D,[ssCtrl,ssAlt],VK_UNKNOWN,[]);
|
ecToggleAssembler: SetResult(VK_D,[ssCtrl,ssAlt],VK_UNKNOWN,[]);
|
||||||
@ -2079,6 +2081,7 @@ begin
|
|||||||
ecToggleBreakPoints : Result:= srkmecToggleBreakPoints;
|
ecToggleBreakPoints : Result:= srkmecToggleBreakPoints;
|
||||||
ecToggleDebuggerOut : Result:= srkmecToggleDebuggerOut;
|
ecToggleDebuggerOut : Result:= srkmecToggleDebuggerOut;
|
||||||
ecToggleLocals : Result:= srkmecToggleLocals;
|
ecToggleLocals : Result:= srkmecToggleLocals;
|
||||||
|
ecViewThreads : Result:= srkmecViewThreads;
|
||||||
ecViewPseudoTerminal : Result:= srkmecViewPseudoTerminal;
|
ecViewPseudoTerminal : Result:= srkmecViewPseudoTerminal;
|
||||||
ecToggleCallStack : Result:= srkmecToggleCallStack;
|
ecToggleCallStack : Result:= srkmecToggleCallStack;
|
||||||
ecToggleRegisters : Result:= srkmecToggleRegisters;
|
ecToggleRegisters : Result:= srkmecToggleRegisters;
|
||||||
@ -2747,6 +2750,7 @@ begin
|
|||||||
AddDefault(C, 'Toggle view Watches', lisKMToggleViewWatches, ecToggleWatches);
|
AddDefault(C, 'Toggle view Watches', lisKMToggleViewWatches, ecToggleWatches);
|
||||||
AddDefault(C, 'Toggle view Breakpoints', lisKMToggleViewBreakpoints, ecToggleBreakPoints);
|
AddDefault(C, 'Toggle view Breakpoints', lisKMToggleViewBreakpoints, ecToggleBreakPoints);
|
||||||
AddDefault(C, 'Toggle view Local Variables', lisKMToggleViewLocalVariables, ecToggleLocals);
|
AddDefault(C, 'Toggle view Local Variables', lisKMToggleViewLocalVariables, ecToggleLocals);
|
||||||
|
AddDefault(C, 'Toggle view Threads', lisKMToggleViewThreads, ecViewThreads);
|
||||||
if HasConsoleSupport then
|
if HasConsoleSupport then
|
||||||
AddDefault(C, 'Toggle view Terminal Output', lisKMToggleViewPseudoTerminal, ecViewPseudoTerminal);
|
AddDefault(C, 'Toggle view Terminal Output', lisKMToggleViewPseudoTerminal, ecViewPseudoTerminal);
|
||||||
AddDefault(C, 'Toggle view Call Stack', lisKMToggleViewCallStack, ecToggleCallStack);
|
AddDefault(C, 'Toggle view Call Stack', lisKMToggleViewCallStack, ecToggleCallStack);
|
||||||
|
@ -304,6 +304,7 @@ resourcestring
|
|||||||
lisMenuViewPseudoTerminal = 'Terminal Output';
|
lisMenuViewPseudoTerminal = 'Terminal Output';
|
||||||
lisMenuViewRegisters = 'Registers';
|
lisMenuViewRegisters = 'Registers';
|
||||||
lisMenuViewCallStack = 'Call Stack';
|
lisMenuViewCallStack = 'Call Stack';
|
||||||
|
lisMenuViewThreads = 'Threads';
|
||||||
lisMenuViewAssembler = 'Assembler';
|
lisMenuViewAssembler = 'Assembler';
|
||||||
lisDbgAsmCopyToClipboard = 'Copy to clipboard';
|
lisDbgAsmCopyToClipboard = 'Copy to clipboard';
|
||||||
lisMenuViewDebugOutput = 'Debug output';
|
lisMenuViewDebugOutput = 'Debug output';
|
||||||
@ -2602,6 +2603,7 @@ resourcestring
|
|||||||
srkmecToggleBreakPoints = 'View breakpoints';
|
srkmecToggleBreakPoints = 'View breakpoints';
|
||||||
srkmecToggleDebuggerOut = 'View debugger output';
|
srkmecToggleDebuggerOut = 'View debugger output';
|
||||||
srkmecToggleLocals = 'View local variables';
|
srkmecToggleLocals = 'View local variables';
|
||||||
|
srkmecViewThreads = 'View Threads';
|
||||||
srkmecViewPseudoTerminal = 'View Terminal Output';
|
srkmecViewPseudoTerminal = 'View Terminal Output';
|
||||||
srkmecTogglecallStack = 'View call stack';
|
srkmecTogglecallStack = 'View call stack';
|
||||||
srkmecToggleRegisters = 'View registers';
|
srkmecToggleRegisters = 'View registers';
|
||||||
@ -2750,6 +2752,7 @@ resourcestring
|
|||||||
lisKMToggleViewWatches = 'Toggle view Watches';
|
lisKMToggleViewWatches = 'Toggle view Watches';
|
||||||
lisKMToggleViewBreakpoints = 'Toggle view Breakpoints';
|
lisKMToggleViewBreakpoints = 'Toggle view Breakpoints';
|
||||||
lisKMToggleViewLocalVariables = 'Toggle view Local Variables';
|
lisKMToggleViewLocalVariables = 'Toggle view Local Variables';
|
||||||
|
lisKMToggleViewThreads = 'Toggle view Threads';
|
||||||
lisKMToggleViewPseudoTerminal = 'Toggle view Terminal Output';
|
lisKMToggleViewPseudoTerminal = 'Toggle view Terminal Output';
|
||||||
lisKMToggleViewCallStack = 'Toggle view Call Stack';
|
lisKMToggleViewCallStack = 'Toggle view Call Stack';
|
||||||
lisKMToggleViewRegisters = 'Toggle view Registers';
|
lisKMToggleViewRegisters = 'Toggle view Registers';
|
||||||
@ -4665,6 +4668,17 @@ resourcestring
|
|||||||
lisRegistersDlgName = 'Name';
|
lisRegistersDlgName = 'Name';
|
||||||
lisRegistersDlgValue = 'Value';
|
lisRegistersDlgValue = 'Value';
|
||||||
|
|
||||||
|
// ThreadDlg
|
||||||
|
lisThreads = 'Threads';
|
||||||
|
lisThreadsId = 'Id';
|
||||||
|
lisThreadsName = 'Name';
|
||||||
|
lisThreadsState = 'State';
|
||||||
|
lisThreadsSrc = 'Source';
|
||||||
|
lisThreadsLine = 'Line';
|
||||||
|
lisThreadsFunc = 'Function';
|
||||||
|
lisThreadsCurrent = 'Current';
|
||||||
|
lisThreadsGoto = 'Goto';
|
||||||
|
|
||||||
// Exception Dialog
|
// Exception Dialog
|
||||||
lisExceptionDialog = 'Debugger Exception Notification';
|
lisExceptionDialog = 'Debugger Exception Notification';
|
||||||
lisBtnBreak = 'Break';
|
lisBtnBreak = 'Break';
|
||||||
|
@ -188,6 +188,7 @@ type
|
|||||||
itmViewLocals: TIDEMenuCommand;
|
itmViewLocals: TIDEMenuCommand;
|
||||||
itmViewRegisters: TIDEMenuCommand;
|
itmViewRegisters: TIDEMenuCommand;
|
||||||
itmViewCallStack: TIDEMenuCommand;
|
itmViewCallStack: TIDEMenuCommand;
|
||||||
|
itmViewThreads: TIDEMenuCommand;
|
||||||
itmViewAssembler: TIDEMenuCommand;
|
itmViewAssembler: TIDEMenuCommand;
|
||||||
itmViewDebugOutput: TIDEMenuCommand;
|
itmViewDebugOutput: TIDEMenuCommand;
|
||||||
itmViewDebugEvents: TIDEMenuCommand;
|
itmViewDebugEvents: TIDEMenuCommand;
|
||||||
|
@ -535,6 +535,7 @@ begin
|
|||||||
itmViewPseudoTerminal := nil;
|
itmViewPseudoTerminal := nil;
|
||||||
CreateMenuItem(itmViewDebugWindows,itmViewRegisters,'itmViewRegisters',lisMenuViewRegisters);
|
CreateMenuItem(itmViewDebugWindows,itmViewRegisters,'itmViewRegisters',lisMenuViewRegisters);
|
||||||
CreateMenuItem(itmViewDebugWindows,itmViewCallStack,'itmViewCallStack',lisMenuViewCallStack,'debugger_call_stack');
|
CreateMenuItem(itmViewDebugWindows,itmViewCallStack,'itmViewCallStack',lisMenuViewCallStack,'debugger_call_stack');
|
||||||
|
CreateMenuItem(itmViewDebugWindows,itmViewThreads,'itmViewThreads',lisMenuViewThreads);
|
||||||
CreateMenuItem(itmViewDebugWindows,itmViewAssembler,'itmViewAssembler',lisMenuViewAssembler);
|
CreateMenuItem(itmViewDebugWindows,itmViewAssembler,'itmViewAssembler',lisMenuViewAssembler);
|
||||||
CreateMenuItem(itmViewDebugWindows,itmViewDebugEvents,'itmViewDebugEvents',lisMenuViewDebugEvents,''{'debugger_events'});
|
CreateMenuItem(itmViewDebugWindows,itmViewDebugEvents,'itmViewDebugEvents',lisMenuViewDebugEvents,''{'debugger_events'});
|
||||||
CreateMenuItem(itmViewDebugWindows,itmViewDebugOutput,'itmViewDebugOutput',lisMenuViewDebugOutput,'debugger_output');
|
CreateMenuItem(itmViewDebugWindows,itmViewDebugOutput,'itmViewDebugOutput',lisMenuViewDebugOutput,'debugger_output');
|
||||||
|
@ -186,6 +186,7 @@ const
|
|||||||
ecToggleAssembler = ecFirstLazarus + 326;
|
ecToggleAssembler = ecFirstLazarus + 326;
|
||||||
ecToggleDebugEvents = ecFirstLazarus + 327;
|
ecToggleDebugEvents = ecFirstLazarus + 327;
|
||||||
ecViewPseudoTerminal = ecFirstLazarus + 328;
|
ecViewPseudoTerminal = ecFirstLazarus + 328;
|
||||||
|
ecViewThreads = ecFirstLazarus + 329;
|
||||||
|
|
||||||
// sourcenotebook commands
|
// sourcenotebook commands
|
||||||
ecNextEditor = ecFirstLazarus + 330;
|
ecNextEditor = ecFirstLazarus + 330;
|
||||||
|
Loading…
Reference in New Issue
Block a user