FpDebug: FpDbgDwarfFreepascal, when searching all units, search "system" unit last. It can contain 16bit PInteger, even if the app is ObjPas. Also prevent the scoped enums true/false/word in sysutils and typinfo. Related to issue #40173

This commit is contained in:
Martin 2023-03-21 11:28:27 +01:00
parent c5057d55ed
commit 73f0e0ea68
3 changed files with 83 additions and 8 deletions

View File

@ -97,6 +97,9 @@ type
destructor Destroy; override;
end;
TFindExportedSymbolsFlag = (fsfIgnoreEnumVals);
TFindExportedSymbolsFlags = set of TFindExportedSymbolsFlag;
{ TFpDwarfInfoSymbolScope }
TFpDwarfInfoSymbolScope = class(TFpDbgSymbolScope)
@ -119,9 +122,9 @@ type
function GetSelfParameter: TFpValueDwarf;
function FindExportedSymbolInUnit(CU: TDwarfCompilationUnit; const ANameInfo: TNameSearchInfo;
out AnInfoEntry: TDwarfInformationEntry; out AnIsExternal: Boolean): Boolean; inline;
out AnInfoEntry: TDwarfInformationEntry; out AnIsExternal: Boolean; AFindFlags: TFindExportedSymbolsFlags = []): Boolean; virtual;
function FindExportedSymbolInUnits(const AName: String; const ANameInfo: TNameSearchInfo;
SkipCompUnit: TDwarfCompilationUnit; out ADbgValue: TFpValue; const OnlyUnitNameLower: String = ''): Boolean;
SkipCompUnit: TDwarfCompilationUnit; out ADbgValue: TFpValue; const OnlyUnitNameLower: String = ''): Boolean; virtual;
function FindSymbolInStructure(const AName: String; const ANameInfo: TNameSearchInfo;
InfoEntry: TDwarfInformationEntry; out ADbgValue: TFpValue): Boolean; virtual;
function FindSymbolInStructureRecursive(const AName: String; const ANameInfo: TNameSearchInfo;
@ -1400,7 +1403,8 @@ end;
function TFpDwarfInfoSymbolScope.FindExportedSymbolInUnit(
CU: TDwarfCompilationUnit; const ANameInfo: TNameSearchInfo; out
AnInfoEntry: TDwarfInformationEntry; out AnIsExternal: Boolean): Boolean;
AnInfoEntry: TDwarfInformationEntry; out AnIsExternal: Boolean;
AFindFlags: TFindExportedSymbolsFlags): Boolean;
var
ExtVal: Integer;
InfoEntry: TDwarfInformationEntry;
@ -1430,7 +1434,7 @@ begin
end
else
if InfoEntry.GoNamedChildEx(ANameInfo) then begin
if InfoEntry.GoNamedChildEx(ANameInfo, False, fsfIgnoreEnumVals in AFindFlags) then begin
if InfoEntry.IsAddressInStartScope(FAddress) then begin
// only variables are marked "external", but types not / so we may need all top level
Result := True;

View File

@ -369,7 +369,7 @@ type
function GoNamedChild(const AName: String): Boolean;
// find in enum too // TODO: control search with a flags param, if needed
function GoNamedChildEx(const ANameInfo: TNameSearchInfo; ASkipArtificial: Boolean = False): Boolean;
function GoNamedChildEx(const ANameInfo: TNameSearchInfo; ASkipArtificial: Boolean = False; ASkipEnumMembers: Boolean = False): Boolean;
// GoNamedChildMatchCaseEx will use
// - UpperName for Hash
// - LowerName for compare
@ -2878,7 +2878,8 @@ begin
end;
function TDwarfInformationEntry.GoNamedChildEx(
const ANameInfo: TNameSearchInfo; ASkipArtificial: Boolean): Boolean;
const ANameInfo: TNameSearchInfo; ASkipArtificial: Boolean;
ASkipEnumMembers: Boolean): Boolean;
var
Val: Integer;
EntryName: PChar;
@ -2909,7 +2910,7 @@ begin
end;
if (sc^.NameHash <> ANameInfo.NameHash) and
(FAbbrev^.tag <> DW_TAG_enumeration_type)
( ASkipEnumMembers or (FAbbrev^.tag <> DW_TAG_enumeration_type) )
then begin
GoNext;
Continue;
@ -2937,7 +2938,7 @@ begin
end;
end;
if FAbbrev^.tag = DW_TAG_enumeration_type then begin
if (not ASkipEnumMembers) and (FAbbrev^.tag = DW_TAG_enumeration_type) then begin
assert(not InEnum, 'nested enum');
InEnum := True;
ParentScopIdx := ScopeIndex;

View File

@ -94,7 +94,19 @@ type
FOuterNestContext: TFpDbgSymbolScope;
FOuterNotFound: Boolean;
FClassVarStaticPrefix: String;
FSystemCU, FSysUtilsCU, FTypInfoCU: TDwarfCompilationUnit;
FFoundSystemInfoEntry: TDwarfInformationEntry;
FInAllUnitSearch, FSearchSpecialCuDone: boolean;
protected
function FindExportedSymbolInUnit(CU: TDwarfCompilationUnit;
const ANameInfo: TNameSearchInfo; out
AnInfoEntry: TDwarfInformationEntry; out AnIsExternal: Boolean;
AFindFlags: TFindExportedSymbolsFlags = []): Boolean; override;
function FindExportedSymbolInUnits(const AName: String;
const ANameInfo: TNameSearchInfo; SkipCompUnit: TDwarfCompilationUnit;
out ADbgValue: TFpValue; const OnlyUnitNameLower: String = ''): Boolean;
override;
function FindLocalSymbol(const AName: String; const ANameInfo: TNameSearchInfo;
InfoEntry: TDwarfInformationEntry; out ADbgValue: TFpValue): Boolean; override;
function FindSymbolInStructure(const AName: String;
@ -562,6 +574,64 @@ end;
var
ParentFpLowerNameInfo, ParentFp2LowerNameInfo: TNameSearchInfo; // case sensitive
function TFpDwarfFreePascalSymbolScope.FindExportedSymbolInUnit(
CU: TDwarfCompilationUnit; const ANameInfo: TNameSearchInfo; out
AnInfoEntry: TDwarfInformationEntry; out AnIsExternal: Boolean;
AFindFlags: TFindExportedSymbolsFlags): Boolean;
begin
// those units have scoped enums, that conflict with common types
if (CU = FSysUtilsCU) or (CU = FTypInfoCU) then
Include(AFindFlags, fsfIgnoreEnumVals);
Result := inherited FindExportedSymbolInUnit(CU, ANameInfo, AnInfoEntry,
AnIsExternal, AFindFlags);
if Result and FInAllUnitSearch and (CU = FSystemCU) then begin
FFoundSystemInfoEntry := AnInfoEntry;
AnInfoEntry := nil;
Result := False;
end;
end;
function TFpDwarfFreePascalSymbolScope.FindExportedSymbolInUnits(
const AName: String; const ANameInfo: TNameSearchInfo;
SkipCompUnit: TDwarfCompilationUnit; out ADbgValue: TFpValue;
const OnlyUnitNameLower: String): Boolean;
var
i: Integer;
CU: TDwarfCompilationUnit;
FoundInfoEntry: TDwarfInformationEntry;
FndIsExternal: Boolean;
s: String;
begin
if not FSearchSpecialCuDone then begin
for i := 0 to Dwarf.CompilationUnitsCount - 1 do begin
CU := Dwarf.CompilationUnits[i];
s := LowerCase(CU.UnitName);
if (s = 'system') then
FSystemCU := CU;
if (s = 'sysutils') then
FSysUtilsCU := CU;
if (s = 'typinfo') and (pos('objpas', LowerCase(CU.FileName)) > 0) then
FTypInfoCU := CU;
end;
FSearchSpecialCuDone := True;
end;
FInAllUnitSearch := True;
FFoundSystemInfoEntry := nil;
Result := inherited FindExportedSymbolInUnits(AName, ANameInfo, SkipCompUnit,
ADbgValue, OnlyUnitNameLower);
FInAllUnitSearch := False;
if (not Result) and (FFoundSystemInfoEntry <> nil) then
ADbgValue := SymbolToValue(TFpSymbolDwarf.CreateSubClass(AName, FFoundSystemInfoEntry));
FFoundSystemInfoEntry.ReleaseReference;
end;
function TFpDwarfFreePascalSymbolScope.FindLocalSymbol(const AName: String;
const ANameInfo: TNameSearchInfo; InfoEntry: TDwarfInformationEntry; out
ADbgValue: TFpValue): Boolean;