FpDebug: Implement finding "address for line" before/after the requested line, if there is no entry for the request.

This commit is contained in:
Martin 2021-12-05 17:49:35 +01:00
parent a691278256
commit df98551a5f
2 changed files with 89 additions and 29 deletions

View File

@ -486,7 +486,8 @@ type
procedure Init; procedure Init;
procedure SetAddressForLine(ALine: Cardinal; AnAddress: TDBGPtr); inline; procedure SetAddressForLine(ALine: Cardinal; AnAddress: TDBGPtr); inline;
function GetAddressesForLine(ALine: Cardinal; var AResultList: TDBGPtrArray; function GetAddressesForLine(ALine: Cardinal; var AResultList: TDBGPtrArray;
NoData: Boolean = False): Boolean; inline; NoData: Boolean = False; AFindSibling: TGetLineAddrFindSibling = fsNone;
AFoundLine: PInteger = nil): Boolean; inline;
// NoData: only return True/False, but nothing in AResultList // NoData: only return True/False, but nothing in AResultList
procedure Compress; procedure Compress;
end; end;
@ -698,7 +699,8 @@ type
procedure WaitForComputeHashes; inline; procedure WaitForComputeHashes; inline;
function GetDefinition(AAbbrevPtr: Pointer; out ADefinition: TDwarfAbbrev): Boolean; inline; function GetDefinition(AAbbrevPtr: Pointer; out ADefinition: TDwarfAbbrev): Boolean; inline;
function GetLineAddressMap(const AFileName: String): PDWarfLineMap; function GetLineAddressMap(const AFileName: String): PDWarfLineMap;
function GetLineAddresses(const AFileName: String; ALine: Cardinal; var AResultList: TDBGPtrArray): boolean; function GetLineAddresses(const AFileName: String; ALine: Cardinal; var AResultList: TDBGPtrArray;
AFindSibling: TGetLineAddrFindSibling = fsNone; AFoundLine: PInteger = nil): boolean;
procedure BuildLineInfo(AAddressInfo: PDwarfAddressInfo; ADoAll: Boolean); procedure BuildLineInfo(AAddressInfo: PDwarfAddressInfo; ADoAll: Boolean);
// On Darwin it could be that the debug-information is not included into the executable by the linker. // On Darwin it could be that the debug-information is not included into the executable by the linker.
// This function is to map object-file addresses into the corresponding addresses in the executable. // This function is to map object-file addresses into the corresponding addresses in the executable.
@ -761,7 +763,8 @@ type
function FindProcStartEndPC(const AAddress: TDbgPtr; out AStartPC, AEndPC: TDBGPtr): boolean; override; function FindProcStartEndPC(const AAddress: TDbgPtr; out AStartPC, AEndPC: TDBGPtr): boolean; override;
//function FindSymbol(const AName: String): TDbgSymbol; override; overload; //function FindSymbol(const AName: String): TDbgSymbol; override; overload;
function GetLineAddresses(const AFileName: String; ALine: Cardinal; var AResultList: TDBGPtrArray): Boolean; override; function GetLineAddresses(const AFileName: String; ALine: Cardinal; var AResultList: TDBGPtrArray;
AFindSibling: TGetLineAddrFindSibling = fsNone; AFoundLine: PInteger = nil): Boolean; override;
function GetLineAddressMap(const AFileName: String): PDWarfLineMap; function GetLineAddressMap(const AFileName: String): PDWarfLineMap;
function LoadCompilationUnits: Integer; function LoadCompilationUnits: Integer;
function PointerFromRVA(ARVA: QWord): Pointer; function PointerFromRVA(ARVA: QWord): Pointer;
@ -3471,37 +3474,89 @@ begin
end; end;
function TDWarfLineMap.GetAddressesForLine(ALine: Cardinal; function TDWarfLineMap.GetAddressesForLine(ALine: Cardinal;
var AResultList: TDBGPtrArray; NoData: Boolean): Boolean; var AResultList: TDBGPtrArray; NoData: Boolean;
AFindSibling: TGetLineAddrFindSibling; AFoundLine: PInteger): Boolean;
var var
idx, offset: TDBGPtr; idx, offset: TDBGPtr;
LineOffsets: Array of Byte; LineOffsets: Array of Byte;
Addresses: Array of TDBGPtr; Addresses: Array of TDBGPtr;
o: Byte; o: Byte;
i, j, k, l: Integer; i, j, k, l, CurOffs: Integer;
begin begin
Result := False; Result := False;
if AFoundLine <> nil then
AFoundLine^ := ALine;
idx := ALine div 256; idx := ALine div 256;
offset := ALine mod 256; offset := ALine mod 256;
if idx >= Length(FLineIndexList) then if idx >= Length(FLineIndexList) then begin
if AFindSibling = fsBefore then begin
idx := Length(FLineIndexList);
offset := 255;
end
else
exit; exit;
end;
repeat
LineOffsets := FLineIndexList[idx].LineOffsets; LineOffsets := FLineIndexList[idx].LineOffsets;
Addresses := FLineIndexList[idx].Addresses; Addresses := FLineIndexList[idx].Addresses;
if Addresses = nil then if Addresses = nil then
case AFindSibling of
fsNone:
exit; exit;
fsBefore: begin
if idx = 0 then
exit;
dec(idx);
offset := 255;
Continue;
end;
fsNext: begin
inc(idx);
if idx >= Length(FLineIndexList) then
exit;
offset := 0;
Continue;
end;
end;
l := Length(LineOffsets); l := Length(LineOffsets);
i := 0; i := 0;
CurOffs := 0;
while (i < l) do begin while (i < l) do begin
o := LineOffsets[i]; o := LineOffsets[i];
if o > offset then exit; CurOffs := CurOffs + o;
if o > offset then begin
case AFindSibling of
fsNone:
exit;
fsBefore: begin
if i > 0 then begin
dec(i);
offset := 0; // found line before
end;
end;
fsNext: begin
offset := 0; // found line after/next
end;
end;
break;
end;
offset := offset - o; offset := offset - o;
if offset = 0 then break; if offset = 0 then
break;
inc(i); inc(i);
end; end;
If (offset > 0) then if offset = 0 then
exit; break;
case AFindSibling of
fsNone: exit;
else continue;
end;
until False;
if AFoundLine <> nil then
AFoundLine^ := 256 * idx + CurOffs;
if NoData then begin if NoData then begin
Result := True; Result := True;
@ -3747,7 +3802,8 @@ begin
end; end;
function TFpDwarfInfo.GetLineAddresses(const AFileName: String; function TFpDwarfInfo.GetLineAddresses(const AFileName: String;
ALine: Cardinal; var AResultList: TDBGPtrArray): Boolean; ALine: Cardinal; var AResultList: TDBGPtrArray;
AFindSibling: TGetLineAddrFindSibling; AFoundLine: PInteger): Boolean;
var var
n: Integer; n: Integer;
CU: TDwarfCompilationUnit; CU: TDwarfCompilationUnit;
@ -3757,7 +3813,7 @@ begin
begin begin
CU := TDwarfCompilationUnit(FCompilationUnits[n]); CU := TDwarfCompilationUnit(FCompilationUnits[n]);
CU.WaitForScopeScan; CU.WaitForScopeScan;
Result := CU.GetLineAddresses(AFileName, ALine, AResultList) or Result; Result := CU.GetLineAddresses(AFileName, ALine, AResultList, AFindSibling, AFoundLine) or Result;
end; end;
end; end;
@ -4702,14 +4758,15 @@ begin
end; end;
function TDwarfCompilationUnit.GetLineAddresses(const AFileName: String; function TDwarfCompilationUnit.GetLineAddresses(const AFileName: String;
ALine: Cardinal; var AResultList: TDBGPtrArray): boolean; ALine: Cardinal; var AResultList: TDBGPtrArray;
AFindSibling: TGetLineAddrFindSibling; AFoundLine: PInteger): boolean;
var var
Map: PDWarfLineMap; Map: PDWarfLineMap;
begin begin
Result := False; Result := False;
Map := GetLineAddressMap(AFileName); Map := GetLineAddressMap(AFileName);
if Map = nil then exit; if Map = nil then exit;
Result := Map^.GetAddressesForLine(ALine, AResultList); Result := Map^.GetAddressesForLine(ALine, AResultList, False, AFindSibling, AFoundLine);
end; end;
function TDwarfCompilationUnit.InitLocateAttributeList(AEntry: Pointer; function TDwarfCompilationUnit.InitLocateAttributeList(AEntry: Pointer;

View File

@ -580,6 +580,7 @@ type
end; end;
{ TDbgInfo } { TDbgInfo }
TGetLineAddrFindSibling = (fsNone, fsBefore, fsNext);
TDbgInfo = class(TObject) TDbgInfo = class(TObject)
private private
@ -602,7 +603,8 @@ type
function FindProcStartEndPC(const AAddress: TDbgPtr; out AStartPC, AEndPC: TDBGPtr): boolean; virtual; function FindProcStartEndPC(const AAddress: TDbgPtr; out AStartPC, AEndPC: TDBGPtr): boolean; virtual;
property HasInfo: Boolean read FHasInfo; property HasInfo: Boolean read FHasInfo;
function GetLineAddresses(const AFileName: String; ALine: Cardinal; var AResultList: TDBGPtrArray): Boolean; virtual; function GetLineAddresses(const AFileName: String; ALine: Cardinal; var AResultList: TDBGPtrArray;
AFindSibling: TGetLineAddrFindSibling = fsNone; AFoundLine: PInteger = nil): Boolean; virtual;
//property MemManager: TFpDbgMemReaderBase read GetMemManager write SetMemManager; //property MemManager: TFpDbgMemReaderBase read GetMemManager write SetMemManager;
property TargetInfo: TTargetDescriptor read FTargetInfo write FTargetInfo; property TargetInfo: TTargetDescriptor read FTargetInfo write FTargetInfo;
property MemManager: TFpDbgMemManager read FMemManager; property MemManager: TFpDbgMemManager read FMemManager;
@ -1758,7 +1760,8 @@ begin
end; end;
function TDbgInfo.GetLineAddresses(const AFileName: String; ALine: Cardinal; function TDbgInfo.GetLineAddresses(const AFileName: String; ALine: Cardinal;
var AResultList: TDBGPtrArray): Boolean; var AResultList: TDBGPtrArray; AFindSibling: TGetLineAddrFindSibling;
AFoundLine: PInteger): Boolean;
begin begin
Result := False; Result := False;
end; end;