mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-10 14:36:09 +02:00
FpDebug: Check char-size for strings. Recognize "UnicodeString", issue #0035340
git-svn-id: trunk@60930 -
This commit is contained in:
parent
3b3bbd67a4
commit
6d1944a6a3
@ -122,7 +122,7 @@ type
|
|||||||
|
|
||||||
TFpDwarfV3FreePascalSymbolTypeArray = class(TFpDwarfFreePascalSymbolTypeArray)
|
TFpDwarfV3FreePascalSymbolTypeArray = class(TFpDwarfFreePascalSymbolTypeArray)
|
||||||
private type
|
private type
|
||||||
TArrayOrStringType = (iasUnknown, iasArray, iasShortString, iasAnsiString);
|
TArrayOrStringType = (iasUnknown, iasArray, iasShortString, iasAnsiString, iasUnicodeString);
|
||||||
private
|
private
|
||||||
FArrayOrStringType: TArrayOrStringType;
|
FArrayOrStringType: TArrayOrStringType;
|
||||||
function GetInternalStringType: TArrayOrStringType;
|
function GetInternalStringType: TArrayOrStringType;
|
||||||
@ -588,6 +588,7 @@ function TFpDwarfV3FreePascalSymbolTypeArray.GetInternalStringType: TArrayOrStri
|
|||||||
var
|
var
|
||||||
Info: TDwarfInformationEntry;
|
Info: TDwarfInformationEntry;
|
||||||
t: Cardinal;
|
t: Cardinal;
|
||||||
|
t2: TFpDbgSymbol;
|
||||||
begin
|
begin
|
||||||
Result := FArrayOrStringType;
|
Result := FArrayOrStringType;
|
||||||
if Result <> iasUnknown then
|
if Result <> iasUnknown then
|
||||||
@ -599,6 +600,10 @@ begin
|
|||||||
Info := InformationEntry.FirstChild;
|
Info := InformationEntry.FirstChild;
|
||||||
if Info = nil then exit;
|
if Info = nil then exit;
|
||||||
|
|
||||||
|
t2 := TypeInfo;
|
||||||
|
if (t2 = nil) or (t2.Kind <> skChar) then
|
||||||
|
exit;
|
||||||
|
|
||||||
while Info.HasValidScope do begin
|
while Info.HasValidScope do begin
|
||||||
t := Info.AbbrevTag;
|
t := Info.AbbrevTag;
|
||||||
if (t = DW_TAG_enumeration_type) then
|
if (t = DW_TAG_enumeration_type) then
|
||||||
@ -610,7 +615,10 @@ begin
|
|||||||
// This is a string
|
// This is a string
|
||||||
// TODO: check the location parser, if it is a reference
|
// TODO: check the location parser, if it is a reference
|
||||||
//FIsShortString := iasShortString;
|
//FIsShortString := iasShortString;
|
||||||
FArrayOrStringType := iasAnsiString;
|
if (t2.Size = 2) then
|
||||||
|
FArrayOrStringType := iasUnicodeString
|
||||||
|
else
|
||||||
|
FArrayOrStringType := iasAnsiString;
|
||||||
Result := FArrayOrStringType;
|
Result := FArrayOrStringType;
|
||||||
break;
|
break;
|
||||||
end;
|
end;
|
||||||
@ -623,7 +631,7 @@ end;
|
|||||||
function TFpDwarfV3FreePascalSymbolTypeArray.GetTypedValueObject(
|
function TFpDwarfV3FreePascalSymbolTypeArray.GetTypedValueObject(
|
||||||
ATypeCast: Boolean): TFpDwarfValue;
|
ATypeCast: Boolean): TFpDwarfValue;
|
||||||
begin
|
begin
|
||||||
if GetInternalStringType in [iasShortString, iasAnsiString] then
|
if GetInternalStringType in [iasShortString, iasAnsiString, iasUnicodeString] then
|
||||||
Result := TFpDwarfV3ValueFreePascalString.Create(Self)
|
Result := TFpDwarfV3ValueFreePascalString.Create(Self)
|
||||||
else
|
else
|
||||||
Result := inherited GetTypedValueObject(ATypeCast);
|
Result := inherited GetTypedValueObject(ATypeCast);
|
||||||
@ -636,6 +644,8 @@ begin
|
|||||||
SetKind(skString);
|
SetKind(skString);
|
||||||
iasAnsiString:
|
iasAnsiString:
|
||||||
SetKind(skString); // TODO
|
SetKind(skString); // TODO
|
||||||
|
iasUnicodeString:
|
||||||
|
SetKind(skWideString);
|
||||||
else
|
else
|
||||||
inherited KindNeeded;
|
inherited KindNeeded;
|
||||||
end;
|
end;
|
||||||
@ -651,7 +661,7 @@ begin
|
|||||||
If not Result then
|
If not Result then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
assert(TypeCastTargetType.Kind = skString, 'TFpDwarfValueArray.IsValidTypeCast: TypeCastTargetType.Kind = skArray');
|
assert(TypeCastTargetType.Kind in [skString, skWideString], 'TFpDwarfValueArray.IsValidTypeCast: TypeCastTargetType.Kind = skArray');
|
||||||
|
|
||||||
f := TypeCastSourceValue.FieldFlags;
|
f := TypeCastSourceValue.FieldFlags;
|
||||||
if (f * [svfAddress, svfSize, svfSizeOfPointer] = [svfAddress]) then
|
if (f * [svfAddress, svfSize, svfSizeOfPointer] = [svfAddress]) then
|
||||||
@ -695,6 +705,7 @@ var
|
|||||||
t, t2: TFpDbgSymbol;
|
t, t2: TFpDbgSymbol;
|
||||||
LowBound, HighBound: Int64;
|
LowBound, HighBound: Int64;
|
||||||
Addr: TFpDbgMemLocation;
|
Addr: TFpDbgMemLocation;
|
||||||
|
WResult: UnicodeString;
|
||||||
begin
|
begin
|
||||||
if FValueDone then
|
if FValueDone then
|
||||||
exit(FValue);
|
exit(FValue);
|
||||||
@ -725,11 +736,21 @@ begin
|
|||||||
if HighBound - LowBound > 5000 then
|
if HighBound - LowBound > 5000 then
|
||||||
HighBound := LowBound + 5000;
|
HighBound := LowBound + 5000;
|
||||||
|
|
||||||
SetLength(Result, HighBound-LowBound+1);
|
if t.Kind = skWideString then begin
|
||||||
|
SetLength(WResult, HighBound-LowBound+1);
|
||||||
|
|
||||||
if not MemManager.ReadMemory(Addr, HighBound-LowBound+1, @Result[1]) then begin
|
if not MemManager.ReadMemory(Addr, (HighBound-LowBound+1)*2, @WResult[1]) then begin
|
||||||
Result := '';
|
WResult := '';
|
||||||
FLastError := MemManager.LastError;
|
FLastError := MemManager.LastError;
|
||||||
|
end;
|
||||||
|
Result := WResult;
|
||||||
|
end else begin
|
||||||
|
SetLength(Result, HighBound-LowBound+1);
|
||||||
|
|
||||||
|
if not MemManager.ReadMemory(Addr, HighBound-LowBound+1, @Result[1]) then begin
|
||||||
|
Result := '';
|
||||||
|
FLastError := MemManager.LastError;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
FValue := Result;
|
FValue := Result;
|
||||||
|
@ -256,6 +256,21 @@ type
|
|||||||
constructor Create(AValue: AnsiString);
|
constructor Create(AValue: AnsiString);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TFpDbgValueConstWideChar }
|
||||||
|
|
||||||
|
TFpDbgValueConstWideChar = class(TFpDbgValue) // skChar / Not for strings
|
||||||
|
private
|
||||||
|
FValue: String;
|
||||||
|
FSigned: Boolean;
|
||||||
|
protected
|
||||||
|
property Value: String read FValue write FValue;
|
||||||
|
function GetKind: TDbgSymbolKind; override;
|
||||||
|
function GetFieldFlags: TFpDbgValueFieldFlags; override;
|
||||||
|
function GetAsString: AnsiString; override;
|
||||||
|
public
|
||||||
|
constructor Create(AValue: AnsiString);
|
||||||
|
end;
|
||||||
|
|
||||||
{ TFpDbgValueConstFloat }
|
{ TFpDbgValueConstFloat }
|
||||||
|
|
||||||
TFpDbgValueConstFloat = class(TFpDbgValue)
|
TFpDbgValueConstFloat = class(TFpDbgValue)
|
||||||
@ -538,6 +553,29 @@ begin
|
|||||||
FValue := AValue;
|
FValue := AValue;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TFpDbgValueConstWideChar }
|
||||||
|
|
||||||
|
function TFpDbgValueConstWideChar.GetKind: TDbgSymbolKind;
|
||||||
|
begin
|
||||||
|
Result := skChar;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TFpDbgValueConstWideChar.GetFieldFlags: TFpDbgValueFieldFlags;
|
||||||
|
begin
|
||||||
|
Result := [svfString]
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TFpDbgValueConstWideChar.GetAsString: AnsiString;
|
||||||
|
begin
|
||||||
|
Result := Value;
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TFpDbgValueConstWideChar.Create(AValue: AnsiString);
|
||||||
|
begin
|
||||||
|
inherited Create;
|
||||||
|
FValue := AValue;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TFpDbgCircularRefCountedObject }
|
{ TFpDbgCircularRefCountedObject }
|
||||||
|
|
||||||
procedure TFpDbgCircularRefCountedObject.DoPlainReferenceAdded;
|
procedure TFpDbgCircularRefCountedObject.DoPlainReferenceAdded;
|
||||||
|
@ -711,6 +711,15 @@ function TFpPascalPrettyPrinter.InternalPrintValue(out APrintedValue: String;
|
|||||||
Result := True;
|
Result := True;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure DoWideString;
|
||||||
|
begin
|
||||||
|
APrintedValue := QuoteText(AValue.AsString);
|
||||||
|
if (ppvCreateDbgType in AFlags) then begin
|
||||||
|
ADBGTypeInfo^ := TDBGType.Create(skWideString, ResTypeName);
|
||||||
|
end;
|
||||||
|
Result := True;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure DoFloat;
|
procedure DoFloat;
|
||||||
begin
|
begin
|
||||||
APrintedValue := FloatToStr(AValue.AsFloat);
|
APrintedValue := FloatToStr(AValue.AsFloat);
|
||||||
@ -1011,7 +1020,7 @@ begin
|
|||||||
skAnsiString: ;
|
skAnsiString: ;
|
||||||
skCurrency: ;
|
skCurrency: ;
|
||||||
skVariant: ;
|
skVariant: ;
|
||||||
skWideString: ;
|
skWideString: DoWideString;
|
||||||
skEnum: DoEnum;
|
skEnum: DoEnum;
|
||||||
skEnumValue: DoEnumVal;
|
skEnumValue: DoEnumVal;
|
||||||
skSet: DoSet;
|
skSet: DoSet;
|
||||||
|
@ -1026,6 +1026,7 @@ var
|
|||||||
ti: TFpDbgSymbol;
|
ti: TFpDbgSymbol;
|
||||||
IsPChar: Boolean;
|
IsPChar: Boolean;
|
||||||
v: String;
|
v: String;
|
||||||
|
w: WideString;
|
||||||
begin
|
begin
|
||||||
Result := nil;
|
Result := nil;
|
||||||
assert(Count >= 2, 'TFpPascalExpressionPartBracketIndex.DoGetResultValue: Count >= 2');
|
assert(Count >= 2, 'TFpPascalExpressionPartBracketIndex.DoGetResultValue: Count >= 2');
|
||||||
@ -1112,7 +1113,31 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
TmpVal2 := TFpDbgValueConstChar.Create(v[Offs]);
|
TmpVal2 := TFpDbgValueConstChar.Create(v[Offs]);
|
||||||
end
|
end;
|
||||||
|
skWideString: begin
|
||||||
|
//TODO: move to FpDwarfValue.member ??
|
||||||
|
if (svfInteger in TmpIndex.FieldFlags) then
|
||||||
|
Offs := TmpIndex.AsInteger
|
||||||
|
else
|
||||||
|
if (svfOrdinal in TmpIndex.FieldFlags) and (TmpIndex.AsCardinal <= high(Int64))
|
||||||
|
then
|
||||||
|
Offs := Int64(TmpIndex.AsCardinal)
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
SetError('Can not calculate Index');
|
||||||
|
TmpVal.ReleaseReference;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
w := TmpVal.AsWideString;
|
||||||
|
if (Offs < 1) or (Offs > Length(w)) then begin
|
||||||
|
SetError('Index out of range');
|
||||||
|
TmpVal.ReleaseReference;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TmpVal2 := TFpDbgValueConstChar.Create(w[Offs]);
|
||||||
|
end;
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
SetError(fpErrTypeHasNoIndex, [GetText]);
|
SetError(fpErrTypeHasNoIndex, [GetText]);
|
||||||
|
Loading…
Reference in New Issue
Block a user