mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-17 04:29:25 +02:00
Debugger: Attach, Darwin, try and get process-list via gdb. Issue #0025302 Patch by Joost van der Sluis
git-svn-id: trunk@43417 -
This commit is contained in:
parent
126c85c628
commit
165fa57622
@ -9,20 +9,10 @@ interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
|
||||
ComCtrls, LCLType, Contnrs, LazarusIDEStrConsts;
|
||||
ComCtrls, LCLType, Contnrs, LazarusIDEStrConsts, BaseDebugManager, Debugger;
|
||||
|
||||
type
|
||||
|
||||
// Used to enumerate running processes.
|
||||
TRunningProcessInfo = class
|
||||
public
|
||||
PID: Cardinal;
|
||||
ImageName: string;
|
||||
constructor Create(APID: Cardinal; const AImageName: string);
|
||||
end;
|
||||
|
||||
TRunningProcessInfoList = TObjectList;
|
||||
|
||||
{ TDebugAttachDialogForm }
|
||||
|
||||
TDebugAttachDialogForm = class(TForm)
|
||||
@ -188,6 +178,9 @@ begin
|
||||
if not Assigned(AList) then
|
||||
Exit;
|
||||
|
||||
// If it is not possible to get the process-list from the debugger,
|
||||
// use NSRunningApplication as fallback method. This list is not complete,
|
||||
// though. But better then nothing.
|
||||
Arr := NSWorkspace.sharedWorkspace.runningApplications;
|
||||
for I := 0 to Arr.count - 1 do
|
||||
begin
|
||||
@ -205,41 +198,34 @@ end;
|
||||
{$endif}
|
||||
{$endif}
|
||||
|
||||
{ TRunningProcessInfo }
|
||||
|
||||
constructor TRunningProcessInfo.Create(APID: Cardinal; const AImageName: string);
|
||||
begin
|
||||
self.PID := APID;
|
||||
self.ImageName := AImageName;
|
||||
end;
|
||||
|
||||
function GetPidForAttach: string;
|
||||
var
|
||||
ProcessList: TRunningProcessInfoList;
|
||||
begin
|
||||
Result := '';
|
||||
|
||||
// Check if we can enumerate processes.
|
||||
if not EnumerateProcesses(nil) then
|
||||
begin
|
||||
// If we can't just ask PID as string.
|
||||
InputQuery(rsAttachTo, rsEnterPID, Result);
|
||||
Exit;
|
||||
end;
|
||||
|
||||
// Enumerate.
|
||||
DebugAttachDialogForm := TDebugAttachDialogForm.Create(nil);
|
||||
ProcessList := TRunningProcessInfoList.Create(True);
|
||||
try
|
||||
ProcessList := TRunningProcessInfoList.Create(True);
|
||||
// Check if we can enumerate processes.
|
||||
if not DebugBoss.FillProcessList(ProcessList) then
|
||||
if not EnumerateProcesses(ProcessList) then
|
||||
begin
|
||||
// If we can't just ask PID as string.
|
||||
InputQuery(rsAttachTo, rsEnterPID, Result);
|
||||
Exit;
|
||||
end;
|
||||
|
||||
// Enumerate.
|
||||
DebugAttachDialogForm := TDebugAttachDialogForm.Create(nil);
|
||||
try
|
||||
EnumerateProcesses(ProcessList);
|
||||
if DebugAttachDialogForm.ChooseProcess(ProcessList, Result) <> mrOK then
|
||||
Result := '';
|
||||
finally
|
||||
FreeAndNil(ProcessList);
|
||||
FreeAndNil(DebugAttachDialogForm);
|
||||
end;
|
||||
|
||||
finally
|
||||
FreeAndNil(DebugAttachDialogForm);
|
||||
FreeAndNil(ProcessList);
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -294,7 +280,9 @@ procedure TDebugAttachDialogForm.btnRefreshClick(Sender: TObject);
|
||||
begin
|
||||
lvProcesses.Items.Clear;
|
||||
FList.Clear;
|
||||
EnumerateProcesses(FList);
|
||||
if not DebugBoss.FillProcessList(FList)
|
||||
then
|
||||
EnumerateProcesses(FList);
|
||||
lvProcesses.Items.Count := FList.Count;
|
||||
end;
|
||||
|
||||
|
@ -39,7 +39,7 @@ interface
|
||||
|
||||
uses
|
||||
TypInfo, Classes, SysUtils, Laz2_XMLCfg, math, FileUtil, LazLoggerBase, LazClasses,
|
||||
LCLProc, LazConfigStorage, DebugUtils, maps;
|
||||
LCLProc, LazConfigStorage, DebugUtils, maps, contnrs;
|
||||
|
||||
type
|
||||
// datatype pointing to data on the target
|
||||
@ -162,6 +162,20 @@ type
|
||||
EDebuggerException = class(Exception);
|
||||
EDBGExceptions = class(EDebuggerException);
|
||||
|
||||
type
|
||||
// Used to enumerate running processes.
|
||||
|
||||
{ TRunningProcessInfo }
|
||||
|
||||
TRunningProcessInfo = class
|
||||
public
|
||||
PID: Cardinal;
|
||||
ImageName: string;
|
||||
constructor Create(APID: Cardinal; const AImageName: string);
|
||||
end;
|
||||
|
||||
TRunningProcessInfoList = TObjectList;
|
||||
|
||||
type
|
||||
{ TDebuggerConfigStore }
|
||||
(* TODO: maybe revert relations. Create this in Debugger, and call environmentoptions for the configstore only? *)
|
||||
@ -2848,6 +2862,7 @@ type
|
||||
function Evaluate(const AExpression: String; var AResult: String;
|
||||
var ATypeInfo: TDBGType;
|
||||
EvalFlags: TDBGEvaluateFlags = []): Boolean; // Evaluates the given expression, returns true if valid
|
||||
function GetProcessList(AList: TRunningProcessInfoList): boolean; virtual;
|
||||
function Modify(const AExpression, AValue: String): Boolean; // Modifies the given expression, returns true if valid
|
||||
function Disassemble(AAddr: TDbgPtr; ABackward: Boolean; out ANextAddr: TDbgPtr;
|
||||
out ADump, AStatement, AFile: String; out ALine: Integer): Boolean; deprecated;
|
||||
@ -3155,6 +3170,14 @@ begin
|
||||
if a > b then Result := a else Result := b;
|
||||
end;
|
||||
|
||||
{ TRunningProcessInfo }
|
||||
|
||||
constructor TRunningProcessInfo.Create(APID: Cardinal; const AImageName: string);
|
||||
begin
|
||||
self.PID := APID;
|
||||
self.ImageName := AImageName;
|
||||
end;
|
||||
|
||||
{ TRegistersFormatList }
|
||||
|
||||
function TRegistersFormatList.GetFormat(AName: String): TRegisterDisplayFormat;
|
||||
@ -6528,6 +6551,11 @@ begin
|
||||
Result := ReqCmd(dcEvaluate, [AExpression, @AResult, @ATypeInfo, Integer(EvalFlags)]);
|
||||
end;
|
||||
|
||||
function TDebugger.GetProcessList(AList: TRunningProcessInfoList): boolean;
|
||||
begin
|
||||
result := false;
|
||||
end;
|
||||
|
||||
class function TDebugger.ExePaths: String;
|
||||
begin
|
||||
Result := '';
|
||||
|
@ -803,6 +803,7 @@ type
|
||||
procedure Init; override; // Initializes external debugger
|
||||
procedure Done; override; // Kills external debugger
|
||||
function GetLocation: TDBGLocationRec; override;
|
||||
function GetProcessList(AList: TRunningProcessInfoList): boolean; override;
|
||||
|
||||
//LockCommandProcessing is more than just QueueExecuteLock
|
||||
//LockCommandProcessing also takes care to run the queue, if unlocked and not already running
|
||||
@ -7288,6 +7289,45 @@ begin
|
||||
Result := FCurrentLocation;
|
||||
end;
|
||||
|
||||
function TGDBMIDebugger.GetProcessList(AList: TRunningProcessInfoList): boolean;
|
||||
{$ifdef darwin}
|
||||
var
|
||||
AResult: TGDBMIExecResult;
|
||||
ARunningProcessInfo: TRunningProcessInfo;
|
||||
pname,pid,aLine: string;
|
||||
s: string;
|
||||
i: integer;
|
||||
{$endif}
|
||||
begin
|
||||
{$ifdef darwin}
|
||||
result := State in [dsIdle, dsStop, dsInit];
|
||||
if not Result then
|
||||
exit;
|
||||
|
||||
ExecuteCommand('info mach-tasks',[],[], AResult);
|
||||
s := AResult.Values;
|
||||
i := pos(sLineBreak,s);
|
||||
while i>0 do
|
||||
begin
|
||||
aLine := trim(copy(s,1,i-1));
|
||||
delete(s,1,i+1);
|
||||
i := pos(' is ', aLine);
|
||||
pid := copy(aLine,1,i-1);
|
||||
pname := copy(aLine,i+4,PosEx(' ',aLine,i+4)-(i+4));
|
||||
|
||||
if pid <> '' then
|
||||
begin
|
||||
ARunningProcessInfo := TRunningProcessInfo.Create(StrToIntDef(pname,-1), pid);
|
||||
AList.Add(ARunningProcessInfo);
|
||||
end;
|
||||
i := pos(sLineBreak,s);
|
||||
end;
|
||||
|
||||
{$else}
|
||||
result := false;
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
procedure TGDBMIDebugger.LockCommandProcessing;
|
||||
begin
|
||||
// Keep a different counter than QueueExecuteLock
|
||||
|
@ -172,6 +172,7 @@ type
|
||||
|
||||
procedure Attach(AProcessID: String); virtual; abstract;
|
||||
procedure Detach; virtual; abstract;
|
||||
function FillProcessList(AList: TRunningProcessInfoList): boolean; virtual; abstract;
|
||||
|
||||
function Evaluate(const AExpression: String; var AResult: String;
|
||||
var ATypeInfo: TDBGType;
|
||||
|
@ -208,6 +208,7 @@ type
|
||||
procedure EndDebugging; override;
|
||||
|
||||
procedure Attach(AProcessID: String); override;
|
||||
function FillProcessList(AList: TRunningProcessInfoList): boolean; override;
|
||||
procedure Detach; override;
|
||||
|
||||
function Evaluate(const AExpression: String; var AResult: String;
|
||||
@ -2640,10 +2641,17 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function TDebugManager.FillProcessList(AList: TRunningProcessInfoList): boolean;
|
||||
begin
|
||||
Result := (not Destroying)
|
||||
and (MainIDE.ToolStatus in [itDebugger, itNone])
|
||||
and (FDebugger <> nil)
|
||||
and FDebugger.GetProcessList(AList);
|
||||
end;
|
||||
|
||||
procedure TDebugManager.Detach;
|
||||
begin
|
||||
FRunTimer.Enabled:=false;
|
||||
Exclude(FManagerStates,dmsWaitForRun);
|
||||
FRunTimer.Enabled:=false; Exclude(FManagerStates,dmsWaitForRun);
|
||||
Exclude(FManagerStates,dmsWaitForAttach);
|
||||
|
||||
SourceEditorManager.ClearExecutionLines;
|
||||
|
Loading…
Reference in New Issue
Block a user