Debugger: Add option to limit converter invocations.

This commit is contained in:
Martin 2022-07-03 01:52:53 +02:00
parent 6243770298
commit 271024d8d9
4 changed files with 100 additions and 27 deletions

View File

@ -44,10 +44,13 @@ type
DEF_MaxStringLen = 10000;
DEF_MaxArrayLen = 512;
DEF_MaxNullStringSearchLen = 10000;
DEF_MaxArrayConversionCnt = 100;
DEF_MaxTotalConversionCnt = 3000;
DEF_MaxStackStringLen = 512;
DEF_MaxStackArrayLen = 16;
DEF_MaxStackNullStringSearchLen = 512;
private
FMaxArrayConversionCnt: QWord;
FMaxArrayLen: QWord;
FMaxMemReadSize: QWord;
FMaxNullStringSearchLen: QWord;
@ -55,6 +58,8 @@ type
FMaxStackNullStringSearchLen: QWord;
FMaxStackStringLen: QWord;
FMaxStringLen: QWord;
FMaxTotalConversionCnt: QWord;
function MaxArrayConversionCntIsStored: Boolean;
function MaxArrayLenIsStored: Boolean;
function MaxMemReadSizeIsStored: Boolean;
function MaxNullStringSearchLenIsStored: Boolean;
@ -62,6 +67,8 @@ type
function MaxStackNullStringSearchLenIsStored: Boolean;
function MaxStackStringLenIsStored: Boolean;
function MaxStringLenIsStored: Boolean;
function MaxTotalConversionCntIsStored: Boolean;
procedure SetMaxArrayConversionCnt(AValue: QWord);
procedure SetMaxArrayLen(AValue: QWord);
procedure SetMaxMemReadSize(AValue: QWord);
procedure SetMaxNullStringSearchLen(AValue: QWord);
@ -69,6 +76,7 @@ type
procedure SetMaxStackNullStringSearchLen(AValue: QWord);
procedure SetMaxStackStringLen(AValue: QWord);
procedure SetMaxStringLen(AValue: QWord);
procedure SetMaxTotalConversionCnt(AValue: QWord);
public
constructor Create;
procedure Assign(Source: TPersistent); override;
@ -79,6 +87,9 @@ type
property MaxArrayLen: QWord read FMaxArrayLen write SetMaxArrayLen stored MaxArrayLenIsStored default DEF_MaxArrayLen;
property MaxNullStringSearchLen: QWord read FMaxNullStringSearchLen write SetMaxNullStringSearchLen stored MaxNullStringSearchLenIsStored default DEF_MaxNullStringSearchLen;
property MaxArrayConversionCnt: QWord read FMaxArrayConversionCnt write SetMaxArrayConversionCnt stored MaxArrayConversionCntIsStored default DEF_MaxArrayConversionCnt;
property MaxTotalConversionCnt: QWord read FMaxTotalConversionCnt write SetMaxTotalConversionCnt stored MaxTotalConversionCntIsStored default DEF_MaxTotalConversionCnt;
property MaxStackStringLen: QWord read FMaxStackStringLen write SetMaxStackStringLen stored MaxStackStringLenIsStored default DEF_MaxStackStringLen;
property MaxStackArrayLen: QWord read FMaxStackArrayLen write SetMaxStackArrayLen stored MaxStackArrayLenIsStored default DEF_MaxStackArrayLen;
property MaxStackNullStringSearchLen: QWord read FMaxStackNullStringSearchLen write SetMaxStackNullStringSearchLen stored MaxStackNullStringSearchLenIsStored default DEF_MaxStackNullStringSearchLen;
@ -211,6 +222,11 @@ begin
Result := FMaxArrayLen <> DEF_MaxArrayLen;
end;
function TFpDebugDebuggerPropertiesMemLimits.MaxArrayConversionCntIsStored: Boolean;
begin
Result := FMaxArrayConversionCnt <> DEF_MaxArrayConversionCnt;
end;
function TFpDebugDebuggerPropertiesMemLimits.MaxMemReadSizeIsStored: Boolean;
begin
Result := FMaxMemReadSize <> DEF_MaxMemReadSize;
@ -241,6 +257,18 @@ begin
Result := FMaxStringLen <> DEF_MaxStringLen;
end;
function TFpDebugDebuggerPropertiesMemLimits.MaxTotalConversionCntIsStored: Boolean;
begin
Result := FMaxTotalConversionCnt <> DEF_MaxTotalConversionCnt;
end;
procedure TFpDebugDebuggerPropertiesMemLimits.SetMaxArrayConversionCnt(
AValue: QWord);
begin
if FMaxArrayConversionCnt = AValue then Exit;
FMaxArrayConversionCnt := AValue;
end;
procedure TFpDebugDebuggerPropertiesMemLimits.SetMaxNullStringSearchLen(AValue: QWord);
begin
if (AValue > FMaxStringLen) then
@ -288,6 +316,13 @@ begin
MaxNullStringSearchLen := MaxNullStringSearchLen;
end;
procedure TFpDebugDebuggerPropertiesMemLimits.SetMaxTotalConversionCnt(
AValue: QWord);
begin
if FMaxTotalConversionCnt = AValue then Exit;
FMaxTotalConversionCnt := AValue;
end;
constructor TFpDebugDebuggerPropertiesMemLimits.Create;
begin
inherited Create;
@ -295,6 +330,8 @@ begin
FMaxStringLen := DEF_MaxStringLen;
FMaxArrayLen := DEF_MaxArrayLen;
FMaxNullStringSearchLen := DEF_MaxNullStringSearchLen ;
FMaxArrayConversionCnt := DEF_MaxArrayConversionCnt;
FMaxTotalConversionCnt := DEF_MaxTotalConversionCnt;
FMaxStackStringLen := DEF_MaxStackStringLen;
FMaxStackArrayLen := DEF_MaxStackArrayLen;
FMaxStackNullStringSearchLen:= DEF_MaxStackNullStringSearchLen;
@ -307,6 +344,8 @@ begin
FMaxStringLen := TFpDebugDebuggerPropertiesMemLimits(Source).FMaxStringLen;
FMaxArrayLen := TFpDebugDebuggerPropertiesMemLimits(Source).FMaxArrayLen;
FMaxNullStringSearchLen := TFpDebugDebuggerPropertiesMemLimits(Source).FMaxNullStringSearchLen;
FMaxArrayConversionCnt := TFpDebugDebuggerPropertiesMemLimits(Source).FMaxArrayConversionCnt;
FMaxTotalConversionCnt := TFpDebugDebuggerPropertiesMemLimits(Source).FMaxTotalConversionCnt;
FMaxStackStringLen := TFpDebugDebuggerPropertiesMemLimits(Source).FMaxStackStringLen;
FMaxStackArrayLen := TFpDebugDebuggerPropertiesMemLimits(Source).FMaxStackArrayLen;
FMaxStackNullStringSearchLen:= TFpDebugDebuggerPropertiesMemLimits(Source).FMaxStackNullStringSearchLen;

View File

@ -1127,6 +1127,8 @@ begin
(ADispFormat <> wdfMemDump) // TODO
then begin
WatchResConv := TFpLazDbgWatchResultConvertor.Create(FExpressionScope.LocationContext);
WatchResConv.MaxArrayConv := TFpDebugDebuggerProperties(FDebugger.GetProperties).MemLimits.MaxArrayConversionCnt;
WatchResConv.MaxTotalConv := TFpDebugDebuggerProperties(FDebugger.GetProperties).MemLimits.MaxTotalConversionCnt;
WatchResConv.ExtraDepth := defExtraDepth in FWatchValue.EvaluateFlags;
WatchResConv.FirstIndexOffs := FWatchValue.FirstIndexOffs;
if not (defSkipValConv in AnEvalFlags) then begin

View File

@ -6,7 +6,7 @@ interface
uses
Classes, SysUtils, FpWatchResultData, FpDbgInfo, FpdMemoryTools,
FpErrorMessages, DbgIntfBaseTypes, FpDebugValueConvertors,
FpErrorMessages, DbgIntfBaseTypes, LazClasses, FpDebugValueConvertors,
FpDebugDebuggerBase, LazDebuggerIntf;
type
@ -20,14 +20,16 @@ type
FValConvList: TFpDbgConverterConfigList;
FValConfig: TFpDbgConverterConfig;
FOuterKind: TDbgSymbolKind;
FOuterKindLvl: Integer;
FMainValueIsArray: Boolean;
FArrayItemConv: TFpDbgValueConverter;
FExtraDephtLevelIsArray: Boolean; // defExtraDepth / RecurseCnt=-1
FExtraDephtLevelItemConv: TFpDbgValueConverter;
FLevelZeroKind: TDbgSymbolKind;
FLevelZeroArrayConv: TFpDbgValueConverter; // All itens in array have same type / optimize and keep converter
FInArray: Boolean;
FMaxTotalConv, FMaxArrayConv, FCurMaxArrayConv: Integer;
function GetValConv(AnFpValue: TFpValue): TFpDbgValueConverter; inline;
procedure SetMaxArrayConv(AValue: Integer);
public
constructor Create(AContext: TFpDbgLocationContext);
destructor Destroy; override;
function DoValueToResData(AnFpValue: TFpValue;
@ -36,6 +38,8 @@ type
property ValConfig: TFpDbgConverterConfig read FValConfig write FValConfig;
property Debugger: TFpDebugDebuggerBase read FDebugger write FDebugger;
property ExpressionScope: TFpDbgSymbolScope read FExpressionScope write FExpressionScope;
property MaxArrayConv: Integer read FMaxArrayConv write SetMaxArrayConv;
property MaxTotalConv: Integer read FMaxTotalConv write FMaxTotalConv;
end;
implementation
@ -70,17 +74,18 @@ begin
end;
end;
constructor TFpLazDbgWatchResultConvertor.Create(AContext: TFpDbgLocationContext
);
procedure TFpLazDbgWatchResultConvertor.SetMaxArrayConv(AValue: Integer);
begin
inherited Create(AContext);
FOuterKindLvl := -99
if FMaxArrayConv = AValue then Exit;
FMaxArrayConv := AValue;
FCurMaxArrayConv := AValue;
end;
destructor TFpLazDbgWatchResultConvertor.Destroy;
begin
inherited Destroy;
FArrayItemConv.ReleaseReference;
FExtraDephtLevelItemConv.ReleaseReference;
FLevelZeroArrayConv.ReleaseReference;
end;
function TFpLazDbgWatchResultConvertor.DoValueToResData(AnFpValue: TFpValue;
@ -89,33 +94,57 @@ var
NewFpVal: TFpValue;
CurConv: TFpDbgValueConverter;
AnResFld: TLzDbgWatchDataIntf;
WasInArray: Boolean;
begin
Result := False;
if RecurseCnt <= 0 then begin
FOuterKind := AnFpValue.Kind;
FOuterKindLvl := RecurseCnt + 1;
if (RecurseCnt = -1) and (AnFpValue.Kind in [skArray]) then
FExtraDephtLevelIsArray := True;
if RecurseCnt = 0 then begin
FLevelZeroKind := AnFpValue.Kind;
FCurMaxArrayConv := FMaxArrayConv;
if not FExtraDephtLevelIsArray then
ReleaseRefAndNil(FLevelZeroArrayConv);
end;
if (RecurseCnt =-1) and (AnFpValue.Kind in [skArray]) then
FMainValueIsArray := True;
WasInArray := FInArray;
if (RecurseCnt >= 0) and (AnFpValue.Kind in [skArray]) then
FInArray := True;
CurConv := nil;
NewFpVal := nil;
try
if (RecurseCnt = 0) and (FMainValueIsArray) then begin
if FArrayItemConv = nil then
FArrayItemConv := GetValConv(AnFpValue);
CurConv := FArrayItemConv;
if (RecurseCnt = 0) and (FExtraDephtLevelIsArray) then begin
if FExtraDephtLevelItemConv = nil then
FExtraDephtLevelItemConv := GetValConv(AnFpValue);
CurConv := FExtraDephtLevelItemConv;
end
else
if (not FMainValueIsArray) and
( (RecurseCnt <= 0) or
( (RecurseCnt = FOuterKindLvl) and (FOuterKind in [skClass, skRecord, skObject, skInstance, skInterface]) )
)
then begin
if (RecurseCnt = 1) and (FLevelZeroKind = skArray) then begin
if FLevelZeroArrayConv = nil then
FLevelZeroArrayConv := GetValConv(AnFpValue);
CurConv := FLevelZeroArrayConv;
end
else begin
CurConv := GetValConv(AnFpValue);
end;
if (CurConv <> nil) then begin
if (FMaxTotalConv <= 0) then
CurConv := nil
else
dec(FMaxTotalConv);
if FInArray then begin
if (FCurMaxArrayConv <= 0) then
CurConv := nil
else
dec(FCurMaxArrayConv);
end;
end;
if (CurConv <> nil) then begin
AnResData.CreateStructure(dstInternal);
AnResFld := AnResData.AddField('', dfvUnknown, []);
@ -134,13 +163,16 @@ begin
AnResData := AnResData.AddField('', dfvUnknown, []);
end;
finally
if CurConv <> FArrayItemConv then
if (CurConv <> FExtraDephtLevelItemConv) and
(CurConv <> FLevelZeroArrayConv)
then
CurConv.ReleaseReference;
NewFpVal.ReleaseReference;
end;
if inherited DoValueToResData(AnFpValue, AnResData) then
Result := True;
FInArray := WasInArray;
end;
end.

View File

@ -271,7 +271,7 @@ begin
expr := trim(cmbExpression.Text);
if expr = '' then Exit;
InputHistories.HistoryLists.Add(ClassName, expr,rltCaseSensitive);
Opts := [defExtraDepth];
Opts := [];
if chkTypeCast.Checked then
Opts := Opts + [defClassAutoCast];
if not chkFpDbgConv.Checked then