FpDebug: refactor for loading MacOs sym in mixed lldb/gdb debug

git-svn-id: trunk@58395 -
This commit is contained in:
martin 2018-06-24 19:31:39 +00:00
parent d1d7164b75
commit a80f8c659c
6 changed files with 75 additions and 40 deletions

View File

@ -665,45 +665,10 @@ end;
procedure TDbgDarwinProcess.InitializeLoaders;
var
dSYMFilename: string;
PrimaryLoader: TDbgImageLoader;
ALoader: TDbgImageLoader;
begin
ALoader:=nil;
PrimaryLoader := TDbgImageLoader.Create(FExecutableFilename);
LoaderList.Add(PrimaryLoader);
// JvdS: Mach-O binaries do not contain DWARF-debug info. Instead this info
// is stored inside the .o files, and the executable contains a map (in stabs-
// format) of all these .o files. An alternative to parsing this map and reading
// those .o files a dSYM-bundle could be used, which could be generated
// with dsymutil.
dSYMFilename:=ChangeFileExt(FExecutableFilename, '.dSYM');
dSYMFilename:=dSYMFilename+'/Contents/Resources/DWARF/'+ExtractFileName(Name);
if ExtractFileExt(dSYMFilename)='.app' then
dSYMFilename := ChangeFileExt(dSYMFilename,'');
if FileExists(dSYMFilename) then
begin
ALoader := TDbgImageLoader.Create(dSYMFilename);
if GUIDToString(ALoader.UUID)<>GUIDToString(PrimaryLoader.UUID) then
begin
log('The unique UUID''s of the executable and the dSYM bundle with debug-info ('+dSYMFilename+') do not match.', dllDebug);
FreeAndNil(ALoader);
end
else
begin
log('Load debug-info from dSYM bundle ('+dSYMFilename+').', dllDebug);
LoaderList.Add(ALoader);
end;
end;
if not assigned(ALoader) then
begin
log('Read debug-info from separate object files.', dllDebug);
TDbgMachoDataSource.LoadSubFiles(PrimaryLoader.SubFiles, LoaderList);
end;
PrimaryLoader.AddToLoaderList(LoaderList);
end;
function TDbgDarwinProcess.CreateThread(AthreadIdentifier: THandle; out IsMainThread: boolean): TDbgThread;

View File

@ -586,7 +586,7 @@ end;
procedure TDbgLinuxProcess.InitializeLoaders;
begin
LoaderList.Add(TDbgImageLoader.Create(Name));
TDbgImageLoader.Create(Name).AddToLoaderList(LoaderList);
end;
function TDbgLinuxProcess.CreateThread(AthreadIdentifier: THandle; out IsMainThread: boolean): TDbgThread;

View File

@ -50,11 +50,15 @@ type
{$ifdef windows}
{$define USE_WIN_FILE_MAPPING}
{$endif}
TDbgImageLoaderList = class;
{ TDbgImageLoader }
TDbgImageLoader = class(TObject)
private
FFileLoader: TDbgFileLoader;
FFileName: String;
FImgReader: TDbgImageReader;
function GetAddressMapList: TDbgAddressMapList;
function GetSubFiles: TStrings;
@ -73,7 +77,9 @@ type
constructor Create(AFileHandle: THandle; ADebugMap: TObject = nil);
{$endif}
destructor Destroy; override;
procedure AddToLoaderList(ALoaderList: TDbgImageLoaderList);
function IsValid: Boolean;
property FileName: String read FFileName; // Empty if using USE_WIN_FILE_MAPPING
property ImageBase: QWord read FImageBase; unimplemented;
Property Image64Bit: Boolean read GetImage64Bit;
property UUID: TGuid read GetUUID;
@ -187,6 +193,7 @@ end;
constructor TDbgImageLoader.Create(AFileName: String; ADebugMap: TObject = nil);
begin
FFileName := AFileName;
FFileLoader := TDbgFileLoader.Create(AFileName);
FImgReader := GetImageReader(FFileLoader, ADebugMap, True);
end;
@ -211,6 +218,12 @@ begin
inherited Destroy;
end;
procedure TDbgImageLoader.AddToLoaderList(ALoaderList: TDbgImageLoaderList);
begin
ALoaderList.Add(Self);
FImgReader.AddSubFilesToLoaderList(ALoaderList, Self);
end;
function TDbgImageLoader.IsValid: Boolean;
begin
Result := FImgReader <> nil;

View File

@ -255,7 +255,7 @@ end;
procedure tDbgWinLibrary.InitializeLoaders;
begin
LoaderList.Add(TDbgImageLoader.Create(FInfo.hFile));
TDbgImageLoader.Create(FInfo.hFile).AddToLoaderList(LoaderList);
end;
constructor tDbgWinLibrary.Create(const AProcess: TDbgProcess;
@ -288,7 +288,7 @@ end;
procedure TDbgWinProcess.InitializeLoaders;
begin
LoaderList.Add(TDbgImageLoader.Create(FInfo.hFile));
TDbgImageLoader.Create(FInfo.hFile).AddToLoaderList(LoaderList);
end;
destructor TDbgWinProcess.Destroy;

View File

@ -85,6 +85,7 @@ type
class function UserName: AnsiString; virtual; abstract;
procedure ParseSymbolTable(AFpSymbolInfo: TfpSymbolList); virtual;
constructor Create({%H-}ASource: TDbgFileLoader; {%H-}ADebugMap: TObject; OwnSource: Boolean); virtual;
procedure AddSubFilesToLoaderList(ALoaderList: TObject; PrimaryLoader: TObject); virtual;
property ImageBase: QWord read FImageBase;
Property Image64Bit: Boolean read FImage64Bit;
@ -288,6 +289,12 @@ begin
inherited Create;
end;
procedure TDbgImageReader.AddSubFilesToLoaderList(ALoaderList: TObject;
PrimaryLoader: TObject);
begin
//
end;
procedure InitDebugInfoLists;
begin

View File

@ -9,7 +9,7 @@ uses
macho, FpImgReaderMachoFile, FpImgReaderBase, LazLoggerBase,
DbgIntfBaseTypes,
lazfglhash,
fpDbgSymTable;
fpDbgSymTable, FpDbgUtil;
type
@ -38,6 +38,7 @@ type
function GetSectionIndex(const SectionName: AnsiString): Integer;
function GetSection(const AName: String): PDbgImageSection; override;
procedure AddSubFilesToLoaderList(ALoaderList: TObject; PrimaryLoader: TObject); override;
public
class function isValid(ASource: TDbgFileLoader): Boolean; override;
class function UserName: AnsiString; override;
@ -298,6 +299,55 @@ begin
fSource.LoadMemory(ex^.Offs, Result^.Size, Result^.RawData);
end;
procedure TDbgMachoDataSource.AddSubFilesToLoaderList(ALoaderList: TObject;
PrimaryLoader: TObject);
var
PLoader: TDbgImageLoader absolute PrimaryLoader;
LList: TDbgImageLoaderList absolute ALoaderList;
ALoader: TDbgImageLoader;
fname, dSYMFilename: String;
i: SizeInt;
begin
// JvdS: Mach-O binaries do not contain DWARF-debug info. Instead this info
// is stored inside the .o files, and the executable contains a map (in stabs-
// format) of all these .o files. An alternative to parsing this map and reading
// those .o files a dSYM-bundle could be used, which could be generated
// with dsymutil.
// PLoader.FileName in Contents/MacOs
ALoader:=nil;
fname := PLoader.FileName;
i := pos('/Contents/MacOs', fname);
if i > 0 then delete(fname, i, Length(fname));
dSYMFilename:=ChangeFileExt(PLoader.FileName, '.dSYM');
dSYMFilename:=dSYMFilename+'/Contents/Resources/DWARF/'+ExtractFileName(fname); // TDbgProcess.Name
if ExtractFileExt(dSYMFilename)='.app' then
dSYMFilename := ChangeFileExt(dSYMFilename,'');
if FileExists(dSYMFilename) then
begin
ALoader := TDbgImageLoader.Create(dSYMFilename);
if GUIDToString(ALoader.UUID)<>GUIDToString(PLoader.UUID) then
begin
Log('The unique UUID''s of the executable and the dSYM bundle with debug-info ('+dSYMFilename+') do not match.');
FreeAndNil(ALoader);
end
else
begin
log('Load debug-info from dSYM bundle ('+dSYMFilename+').');
LList.Add(ALoader);
end;
end;
if not assigned(ALoader) then
begin
log('Read debug-info from separate object files.');
TDbgMachoDataSource.LoadSubFiles(PLoader.SubFiles, LList);
end;
end;
constructor TDbgMachoDataSource.Create(ASource: TDbgFileLoader; ADebugMap: TObject; OwnSource: Boolean);
const
SymbolsSectionName : array [Boolean] of AnsiString = (_symbol, _symbolstrings);