mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-17 17:39:20 +02:00
Debugger: improve SysVarToLStr - Improve error handling
This commit is contained in:
parent
720538be97
commit
b54ac53cca
@ -5,8 +5,9 @@ unit FpDebuggerResultData;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, FpWatchResultData, FpDbgInfo, DbgIntfBaseTypes,
|
Classes, SysUtils, FpWatchResultData, FpDbgInfo, FpdMemoryTools,
|
||||||
FpDebugValueConvertors, FpDebugDebuggerBase, LazDebuggerIntf;
|
DbgIntfBaseTypes, FpDebugValueConvertors, FpDebugDebuggerBase,
|
||||||
|
LazDebuggerIntf;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
@ -20,11 +21,13 @@ type
|
|||||||
FValConfig: TFpDbgConverterConfig;
|
FValConfig: TFpDbgConverterConfig;
|
||||||
|
|
||||||
FOuterKind: TDbgSymbolKind;
|
FOuterKind: TDbgSymbolKind;
|
||||||
|
FOuterKindLvl: Integer;
|
||||||
FMainValueIsArray: Boolean;
|
FMainValueIsArray: Boolean;
|
||||||
FArrayItemConv: TFpDbgValueConverter;
|
FArrayItemConv: TFpDbgValueConverter;
|
||||||
|
|
||||||
function GetValConv(AnFpValue: TFpValue): TFpDbgValueConverter; inline;
|
function GetValConv(AnFpValue: TFpValue): TFpDbgValueConverter; inline;
|
||||||
public
|
public
|
||||||
|
constructor Create(AContext: TFpDbgLocationContext);
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
|
|
||||||
function DoValueToResData(AnFpValue: TFpValue;
|
function DoValueToResData(AnFpValue: TFpValue;
|
||||||
@ -67,6 +70,13 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
constructor TFpLazDbgWatchResultConvertor.Create(AContext: TFpDbgLocationContext
|
||||||
|
);
|
||||||
|
begin
|
||||||
|
inherited Create(AContext);
|
||||||
|
FOuterKindLvl := -99
|
||||||
|
end;
|
||||||
|
|
||||||
destructor TFpLazDbgWatchResultConvertor.Destroy;
|
destructor TFpLazDbgWatchResultConvertor.Destroy;
|
||||||
begin
|
begin
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
@ -76,18 +86,21 @@ end;
|
|||||||
function TFpLazDbgWatchResultConvertor.DoValueToResData(AnFpValue: TFpValue;
|
function TFpLazDbgWatchResultConvertor.DoValueToResData(AnFpValue: TFpValue;
|
||||||
AnResData: TLzDbgWatchDataIntf): Boolean;
|
AnResData: TLzDbgWatchDataIntf): Boolean;
|
||||||
var
|
var
|
||||||
NewRes: TFpValue;
|
NewFpVal: TFpValue;
|
||||||
CurConv: TFpDbgValueConverter;
|
CurConv: TFpDbgValueConverter;
|
||||||
|
AnResFld: TLzDbgWatchDataIntf;
|
||||||
begin
|
begin
|
||||||
NewRes := nil;
|
|
||||||
Result := False;
|
Result := False;
|
||||||
if RecurseCnt = 0 then
|
if RecurseCnt <= 0 then begin
|
||||||
FOuterKind := AnFpValue.Kind;
|
FOuterKind := AnFpValue.Kind;
|
||||||
|
FOuterKindLvl := RecurseCnt + 1;
|
||||||
|
end;
|
||||||
|
|
||||||
if (RecurseCnt =-1) and (AnFpValue.Kind in [skArray]) then
|
if (RecurseCnt =-1) and (AnFpValue.Kind in [skArray]) then
|
||||||
FMainValueIsArray := True;
|
FMainValueIsArray := True;
|
||||||
|
|
||||||
CurConv := nil;
|
CurConv := nil;
|
||||||
|
NewFpVal := nil;
|
||||||
try
|
try
|
||||||
if (RecurseCnt = 0) and (FMainValueIsArray) then begin
|
if (RecurseCnt = 0) and (FMainValueIsArray) then begin
|
||||||
if FArrayItemConv = nil then
|
if FArrayItemConv = nil then
|
||||||
@ -96,31 +109,35 @@ begin
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
if (not FMainValueIsArray) and
|
if (not FMainValueIsArray) and
|
||||||
( (RecurseCnt = 0) or
|
( (RecurseCnt <= 0) or
|
||||||
( (RecurseCnt = 1) and (FOuterKind in [skClass, skRecord, skObject, skInstance, skInterface]) )
|
( (RecurseCnt = FOuterKindLvl) and (FOuterKind in [skClass, skRecord, skObject, skInstance, skInterface]) )
|
||||||
)
|
)
|
||||||
then begin
|
then begin
|
||||||
CurConv := GetValConv(AnFpValue);
|
CurConv := GetValConv(AnFpValue);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if (CurConv <> nil) then begin
|
if (CurConv <> nil) then begin
|
||||||
NewRes := CurConv.ConvertValue(AnFpValue, Debugger, ExpressionScope);
|
AnResData.CreateStructure(dstInternal);
|
||||||
if NewRes <> nil then
|
AnResFld := AnResData.AddField('', dfvUnknown, []);
|
||||||
AnFpValue := NewRes
|
|
||||||
else
|
NewFpVal := CurConv.ConvertValue(AnFpValue, Debugger, ExpressionScope);
|
||||||
if FMainValueIsArray then begin
|
if NewFpVal <> nil then begin
|
||||||
AnResData.CreateError('Conversion failed');
|
Result := inherited DoValueToResData(NewFpVal, AnResFld);
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
AnResFld.CreateError('Conversion failed');
|
||||||
Result := True;
|
Result := True;
|
||||||
exit;
|
|
||||||
end;
|
end;
|
||||||
|
AnResData := AnResData.AddField('', dfvUnknown, []);
|
||||||
end;
|
end;
|
||||||
|
finally
|
||||||
if CurConv <> FArrayItemConv then
|
if CurConv <> FArrayItemConv then
|
||||||
CurConv.ReleaseReference;
|
CurConv.ReleaseReference;
|
||||||
|
NewFpVal.ReleaseReference;
|
||||||
Result := inherited DoValueToResData(AnFpValue, AnResData);
|
|
||||||
finally
|
|
||||||
NewRes.ReleaseReference;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
if inherited DoValueToResData(AnFpValue, AnResData) then
|
||||||
|
Result := True;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
@ -292,18 +292,28 @@ function TFpDbgValueConverterVariantToLStr.ConvertValue(ASourceValue: TFpValue;
|
|||||||
AnFpDebugger: TFpDebugDebuggerBase; AnExpressionScope: TFpDbgSymbolScope
|
AnFpDebugger: TFpDebugDebuggerBase; AnExpressionScope: TFpDbgSymbolScope
|
||||||
): TFpValue;
|
): TFpValue;
|
||||||
var
|
var
|
||||||
NewResult, ProcVal: TFpValue;
|
NewResult, ProcVal, m: TFpValue;
|
||||||
ProcSym, StringDecRefSymbol: TFpSymbol;
|
ProcSym, StringDecRefSymbol: TFpSymbol;
|
||||||
CallContext: TFpDbgInfoCallContext;
|
CallContext: TFpDbgInfoCallContext;
|
||||||
StringAddr, ProcAddr: TDbgPtr;
|
StringAddr, ProcAddr: TDbgPtr;
|
||||||
ProcLoc: TFpDbgMemLocation;
|
ProcLoc: TFpDbgMemLocation;
|
||||||
|
r: Boolean;
|
||||||
begin
|
begin
|
||||||
Result := nil;
|
Result := nil;
|
||||||
if (ASourceValue.Kind <> skRecord) //or
|
if not (
|
||||||
//(ASourceValue.MemberCount <> 2) or
|
(ASourceValue.Kind = skRecord) and
|
||||||
//(SizeToFullBytes(ASourceValue.Member[0].DataSize) <> 2)
|
( (ASourceValue.MemberCount = 0) or
|
||||||
|
(ASourceValue.MemberCount >= 2)
|
||||||
|
) )
|
||||||
then
|
then
|
||||||
exit;
|
exit;
|
||||||
|
if (ASourceValue.MemberCount >= 2) then begin
|
||||||
|
m := ASourceValue.Member[0];
|
||||||
|
r := SizeToFullBytes(m.DataSize) <> 2;
|
||||||
|
m.ReleaseReference;
|
||||||
|
if r then
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
ProcVal := nil;
|
ProcVal := nil;
|
||||||
ProcSym := nil;
|
ProcSym := nil;
|
||||||
@ -349,7 +359,7 @@ begin
|
|||||||
try
|
try
|
||||||
CallContext.AddStringResult;
|
CallContext.AddStringResult;
|
||||||
CallContext.FinalizeParams; // force the string as first param (32bit) // TODO
|
CallContext.FinalizeParams; // force the string as first param (32bit) // TODO
|
||||||
CallContext.AddOrdinalParam(nil, ASourceValue.Address.Address);
|
CallContext.AddOrdinalParam(nil, ASourceValue.DataAddress.Address);
|
||||||
AnFpDebugger.DbgController.ProcessLoop;
|
AnFpDebugger.DbgController.ProcessLoop;
|
||||||
|
|
||||||
if not CallContext.IsValid then
|
if not CallContext.IsValid then
|
||||||
|
@ -1980,6 +1980,7 @@ var
|
|||||||
Src: TCommonSource;
|
Src: TCommonSource;
|
||||||
BrkPrg: TDBGBreakPoint;
|
BrkPrg: TDBGBreakPoint;
|
||||||
obj: TFpDbgConverterConfig;
|
obj: TFpDbgConverterConfig;
|
||||||
|
i, c: Integer;
|
||||||
begin
|
begin
|
||||||
if SkipTest then exit;
|
if SkipTest then exit;
|
||||||
if not TestControlCanTest(ControlTestWatchFunctVariant) then exit;
|
if not TestControlCanTest(ControlTestWatchFunctVariant) then exit;
|
||||||
@ -2014,9 +2015,39 @@ begin
|
|||||||
ValueConverterConfigList.Add(obj);
|
ValueConverterConfigList.Add(obj);
|
||||||
|
|
||||||
t.Clear;
|
t.Clear;
|
||||||
t.Add('variant to lstr', 'variant1', weAnsiStr('102'))
|
t.Add('variant1 to lstr', 'variant1', weAnsiStr('102'));
|
||||||
.IgnTypeName
|
t.Add('variant2 to lstr', 'variant2', weAnsiStr('True'));
|
||||||
.IgnData([], Compiler.Version < 029999);
|
|
||||||
|
t.Add('rec variant1 to lstr', 'v_rec.variant1', weAnsiStr('103'));
|
||||||
|
t.Add('rec variant2 to lstr', 'v_rec.variant2', weAnsiStr('False'));
|
||||||
|
|
||||||
|
t.Add('array variant1 to lstr', 'v_array[3]', weAnsiStr('104'));
|
||||||
|
t.Add('array variant2 to lstr', 'v_array[4]', weAnsiStr('True'));
|
||||||
|
|
||||||
|
|
||||||
|
c := t.Count;
|
||||||
|
t.Add('Extra-depth: variant1 to lstr', 'variant1', weAnsiStr('102'));
|
||||||
|
t.Add('Extra-depth: variant2 to lstr', 'variant2', weAnsiStr('True'));
|
||||||
|
|
||||||
|
t.Add('Extra-depth: rec variant1 to lstr', 'v_rec.variant1', weAnsiStr('103'));
|
||||||
|
t.Add('Extra-depth: rec variant2 to lstr', 'v_rec.variant2', weAnsiStr('False'));
|
||||||
|
|
||||||
|
t.Add('Extra-depth: array variant1 to lstr', 'v_array[3]', weAnsiStr('104'));
|
||||||
|
t.Add('Extra-depth: array variant2 to lstr', 'v_array[4]', weAnsiStr('True'));
|
||||||
|
|
||||||
|
for i := c to t.Count-1 do
|
||||||
|
t.Tests[i]^.TstWatch.EvaluateFlags := t.Tests[i]^.TstWatch.EvaluateFlags + [defExtraDepth];
|
||||||
|
|
||||||
|
|
||||||
|
for i := 0 to t.Count-1 do
|
||||||
|
t.Tests[i].AddFlag(ehNoTypeInfo);
|
||||||
|
|
||||||
|
if Compiler.Version < 029999 then
|
||||||
|
for i := 0 to t.Count-1 do
|
||||||
|
t.Tests[i]
|
||||||
|
.IgnTypeName
|
||||||
|
.IgnData([], Compiler.Version < 029999);
|
||||||
|
|
||||||
t.EvaluateWatches;
|
t.EvaluateWatches;
|
||||||
t.CheckResults;
|
t.CheckResults;
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ type
|
|||||||
|
|
||||||
TLzDbgFloatPrecission = (dfpSingle, dfpDouble, dfpExtended);
|
TLzDbgFloatPrecission = (dfpSingle, dfpDouble, dfpExtended);
|
||||||
// TLzDbgSetData = bitpacked array [0..255] of boolean;
|
// TLzDbgSetData = bitpacked array [0..255] of boolean;
|
||||||
TLzDbgStructType = (dstUnknown, dstRecord, dstObject, dstClass, dstInterface);
|
TLzDbgStructType = (dstUnknown, dstRecord, dstObject, dstClass, dstInterface, dstInternal);
|
||||||
TLzDbgArrayType = (datUnknown, datDynArray, datStatArray);
|
TLzDbgArrayType = (datUnknown, datDynArray, datStatArray);
|
||||||
TLzDbgFieldVisibility = (dfvUnknown, dfvPrivate, dfvProtected, dfvPublic, dfvPublished);
|
TLzDbgFieldVisibility = (dfvUnknown, dfvPrivate, dfvProtected, dfvPublic, dfvPublished);
|
||||||
TLzDbgFieldFlag = (dffClass, dffAbstract, dffVirtual, dffOverwritten, dffConstructor, dffDestructor);
|
TLzDbgFieldFlag = (dffClass, dffAbstract, dffVirtual, dffOverwritten, dffConstructor, dffDestructor);
|
||||||
|
Binary file not shown.
@ -76,6 +76,12 @@ var
|
|||||||
InterfacedObject, InterfacedObject2: TInterfacedObject;
|
InterfacedObject, InterfacedObject2: TInterfacedObject;
|
||||||
|
|
||||||
variant1: variant;
|
variant1: variant;
|
||||||
|
variant2: variant;
|
||||||
|
v_rec: record
|
||||||
|
variant1: variant;
|
||||||
|
variant2: variant;
|
||||||
|
end;
|
||||||
|
v_array: array [3..4] of variant;
|
||||||
|
|
||||||
type
|
type
|
||||||
TClass1 = class;
|
TClass1 = class;
|
||||||
@ -881,6 +887,12 @@ begin
|
|||||||
FuncIntAdd(1,1);
|
FuncIntAdd(1,1);
|
||||||
FuncTooManyArg(1,1,1,1,1,1,1,1,1,1,1,1);
|
FuncTooManyArg(1,1,1,1,1,1,1,1,1,1,1,1);
|
||||||
variant1 := 102;
|
variant1 := 102;
|
||||||
|
variant2 := True;
|
||||||
|
v_rec.variant1 := 103;
|
||||||
|
v_rec.variant2 := False;
|
||||||
|
v_array[3] := 104;
|
||||||
|
v_array[4] := True;
|
||||||
|
|
||||||
{$if FPC_FULLVERSION >= 30000}
|
{$if FPC_FULLVERSION >= 30000}
|
||||||
dummy1 := nil;
|
dummy1 := nil;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
@ -1090,6 +1102,8 @@ begin
|
|||||||
MyClass1.MethFoo();
|
MyClass1.MethFoo();
|
||||||
|
|
||||||
MyClass2.BaseMethFoo();
|
MyClass2.BaseMethFoo();
|
||||||
|
variant1 := 102;
|
||||||
|
variant2 := True;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@ -1366,6 +1366,13 @@ begin
|
|||||||
Stack := TstStackFrame;
|
Stack := TstStackFrame;
|
||||||
WatchVal := TstWatch.Values[Thread, Stack];
|
WatchVal := TstWatch.Values[Thread, Stack];
|
||||||
Context.WatchRes := WatchVal.ResultData;
|
Context.WatchRes := WatchVal.ResultData;
|
||||||
|
if (Context.WatchRes <> nil) and
|
||||||
|
(Context.WatchRes.ValueKind = rdkStruct) and
|
||||||
|
(Context.WatchRes.StructType = dstInternal) and
|
||||||
|
(Context.WatchRes.FieldCount > 0)
|
||||||
|
then
|
||||||
|
Context.WatchRes := Context.WatchRes.Fields[0].Field;
|
||||||
|
|
||||||
Context.WatchTpInf := WatchVal.TypeInfo;
|
Context.WatchTpInf := WatchVal.TypeInfo;
|
||||||
|
|
||||||
if not VerifyDebuggerState then
|
if not VerifyDebuggerState then
|
||||||
|
@ -109,6 +109,7 @@ type
|
|||||||
FWatchPrinter: TWatchResultPrinter;
|
FWatchPrinter: TWatchResultPrinter;
|
||||||
FInspectWatches: TCurrentWatches;
|
FInspectWatches: TCurrentWatches;
|
||||||
FCurrentWatchValue: TIdeWatchValue;
|
FCurrentWatchValue: TIdeWatchValue;
|
||||||
|
FCurrentResData: TWatchResultData;
|
||||||
FHumanReadable: ansistring;
|
FHumanReadable: ansistring;
|
||||||
FGridData: TStringGrid;
|
FGridData: TStringGrid;
|
||||||
FGridMethods: TStringGrid;
|
FGridMethods: TStringGrid;
|
||||||
@ -231,7 +232,7 @@ var
|
|||||||
Res: TWatchResultData;
|
Res: TWatchResultData;
|
||||||
v: String;
|
v: String;
|
||||||
begin
|
begin
|
||||||
Res := FCurrentWatchValue.ResultData;
|
Res := FCurrentResData;
|
||||||
|
|
||||||
DataPage.TabVisible:=true;
|
DataPage.TabVisible:=true;
|
||||||
PropertiesPage.TabVisible:=false;
|
PropertiesPage.TabVisible:=false;
|
||||||
@ -259,7 +260,7 @@ var
|
|||||||
Res: TWatchResultData;
|
Res: TWatchResultData;
|
||||||
v: String;
|
v: String;
|
||||||
begin
|
begin
|
||||||
Res := FCurrentWatchValue.ResultData;
|
Res := FCurrentResData;
|
||||||
DataPage.TabVisible:=true;
|
DataPage.TabVisible:=true;
|
||||||
PropertiesPage.TabVisible:=false;
|
PropertiesPage.TabVisible:=false;
|
||||||
MethodsPage.TabVisible:=false;
|
MethodsPage.TabVisible:=false;
|
||||||
@ -295,7 +296,7 @@ var
|
|||||||
Res: TWatchResultData;
|
Res: TWatchResultData;
|
||||||
v: String;
|
v: String;
|
||||||
begin
|
begin
|
||||||
Res := FCurrentWatchValue.ResultData;
|
Res := FCurrentResData;
|
||||||
|
|
||||||
DataPage.TabVisible:=true;
|
DataPage.TabVisible:=true;
|
||||||
PropertiesPage.TabVisible:=false;
|
PropertiesPage.TabVisible:=false;
|
||||||
@ -345,7 +346,7 @@ begin
|
|||||||
btnColType.Enabled := True;
|
btnColType.Enabled := True;
|
||||||
btnColVisibility.Enabled := False;
|
btnColVisibility.Enabled := False;
|
||||||
|
|
||||||
Res := FCurrentWatchValue.ResultData;
|
Res := FCurrentResData;
|
||||||
StatusBar1.SimpleText:=ShortenedExpression+': '+Res.TypeName + ' Len: ' + IntToStr(Res.ArrayLength);
|
StatusBar1.SimpleText:=ShortenedExpression+': '+Res.TypeName + ' Len: ' + IntToStr(Res.ArrayLength);
|
||||||
|
|
||||||
LowBnd := Res.LowBound;
|
LowBnd := Res.LowBound;
|
||||||
@ -403,7 +404,7 @@ var
|
|||||||
FldInfo: TWatchResultDataFieldInfo;
|
FldInfo: TWatchResultDataFieldInfo;
|
||||||
AnchType: String;
|
AnchType: String;
|
||||||
begin
|
begin
|
||||||
Res := FCurrentWatchValue.ResultData;
|
Res := FCurrentResData;
|
||||||
|
|
||||||
FGridData.Columns[0].Visible := (Res.StructType in [dstClass, dstObject]) and btnColClass.Down; // anchestor
|
FGridData.Columns[0].Visible := (Res.StructType in [dstClass, dstObject]) and btnColClass.Down; // anchestor
|
||||||
FGridData.Columns[2].Visible := btnColType.Down; // typename
|
FGridData.Columns[2].Visible := btnColType.Down; // typename
|
||||||
@ -540,6 +541,7 @@ end;
|
|||||||
procedure TIDEInspectDlg.FormShow(Sender: TObject);
|
procedure TIDEInspectDlg.FormShow(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
ReleaseRefAndNil(FCurrentWatchValue);
|
ReleaseRefAndNil(FCurrentWatchValue);
|
||||||
|
FCurrentResData := nil;
|
||||||
FInspectWatches.Clear;
|
FInspectWatches.Clear;
|
||||||
UpdateData;
|
UpdateData;
|
||||||
end;
|
end;
|
||||||
@ -618,8 +620,8 @@ begin
|
|||||||
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if FCurrentWatchValue.ResultData <> nil then begin
|
if FCurrentResData <> nil then begin
|
||||||
case FCurrentWatchValue.ResultData.ValueKind of
|
case FCurrentResData.ValueKind of
|
||||||
rdkPointerVal: begin
|
rdkPointerVal: begin
|
||||||
i := FGridData.Row;
|
i := FGridData.Row;
|
||||||
if (i < 1) or (i >= FGridData.RowCount) then exit;
|
if (i < 1) or (i >= FGridData.RowCount) then exit;
|
||||||
@ -640,7 +642,7 @@ begin
|
|||||||
if (i < 1) or (i >= FGridData.RowCount) then exit;
|
if (i < 1) or (i >= FGridData.RowCount) then exit;
|
||||||
s := FGridData.Cells[1, i];
|
s := FGridData.Cells[1, i];
|
||||||
|
|
||||||
if btnUseInstance.Down and (FCurrentWatchValue.ResultData.StructType in [dstClass, dstObject]) then
|
if btnUseInstance.Down and (FCurrentResData.StructType in [dstClass, dstObject]) then
|
||||||
Execute(FGridData.Cells[0, i] + '(' + FExpression + ').' + s)
|
Execute(FGridData.Cells[0, i] + '(' + FExpression + ').' + s)
|
||||||
else
|
else
|
||||||
Execute(FExpression + '.' + s);
|
Execute(FExpression + '.' + s);
|
||||||
@ -657,7 +659,7 @@ begin
|
|||||||
if ( (FCurrentWatchValue.TypeInfo <> nil) and
|
if ( (FCurrentWatchValue.TypeInfo <> nil) and
|
||||||
(FCurrentWatchValue.TypeInfo.Kind = skClass)
|
(FCurrentWatchValue.TypeInfo.Kind = skClass)
|
||||||
) or
|
) or
|
||||||
( FCurrentWatchValue.ResultData.StructType in [dstClass, dstObject] )
|
( FCurrentResData.StructType in [dstClass, dstObject] )
|
||||||
then begin
|
then begin
|
||||||
FGridData.Columns[0].Visible := btnColClass.Down;
|
FGridData.Columns[0].Visible := btnColClass.Down;
|
||||||
FGridData.Columns[4].Visible := btnColVisibility.Down;
|
FGridData.Columns[4].Visible := btnColVisibility.Down;
|
||||||
@ -677,6 +679,7 @@ begin
|
|||||||
then begin
|
then begin
|
||||||
btnPower.ImageIndex := FPowerImgIdx;
|
btnPower.ImageIndex := FPowerImgIdx;
|
||||||
ReleaseRefAndNil(FCurrentWatchValue);
|
ReleaseRefAndNil(FCurrentWatchValue);
|
||||||
|
FCurrentResData := nil;
|
||||||
FInspectWatches.Clear;
|
FInspectWatches.Clear;
|
||||||
UpdateData;
|
UpdateData;
|
||||||
end
|
end
|
||||||
@ -1261,6 +1264,7 @@ begin
|
|||||||
DebugBoss.UnregisterStateChangeHandler(@DoDebuggerState);
|
DebugBoss.UnregisterStateChangeHandler(@DoDebuggerState);
|
||||||
DebugBoss.UnregisterWatchesInvalidatedHandler(@DoWatchesInvalidated);
|
DebugBoss.UnregisterWatchesInvalidatedHandler(@DoWatchesInvalidated);
|
||||||
ReleaseRefAndNil(FCurrentWatchValue);
|
ReleaseRefAndNil(FCurrentWatchValue);
|
||||||
|
FCurrentResData := nil;
|
||||||
FreeAndNil(FHistory);
|
FreeAndNil(FHistory);
|
||||||
FreeAndNil(FWatchPrinter);
|
FreeAndNil(FWatchPrinter);
|
||||||
//FreeAndNil(FDataGridHook);
|
//FreeAndNil(FDataGridHook);
|
||||||
@ -1347,9 +1351,10 @@ begin
|
|||||||
|
|
||||||
TimerClearData.Enabled := False;
|
TimerClearData.Enabled := False;
|
||||||
|
|
||||||
|
FCurrentResData := nil;
|
||||||
FAlternateExpression := '';
|
FAlternateExpression := '';
|
||||||
FExpressionWasEvaluated := True;
|
FExpressionWasEvaluated := True;
|
||||||
FHumanReadable := FWatchPrinter.PrintWatchValue(FCurrentWatchValue.ResultData, wdfStructure);
|
FHumanReadable := FWatchPrinter.PrintWatchValue(FCurrentResData, wdfStructure);
|
||||||
|
|
||||||
if FCurrentWatchValue.Validity = ddsValid then begin
|
if FCurrentWatchValue.Validity = ddsValid then begin
|
||||||
ArrayNavigationBar1.Visible := False;
|
ArrayNavigationBar1.Visible := False;
|
||||||
@ -1378,9 +1383,27 @@ begin
|
|||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
|
FCurrentResData := FCurrentWatchValue.ResultData;
|
||||||
// resultdata
|
// resultdata
|
||||||
ArrayNavigationBar1.Visible := FCurrentWatchValue.ResultData.ValueKind = rdkArray;
|
|
||||||
case FCurrentWatchValue.ResultData.ValueKind of
|
if (FCurrentResData.ValueKind = rdkStruct) and
|
||||||
|
(FCurrentResData.StructType = dstInternal)
|
||||||
|
then begin
|
||||||
|
if (FCurrentResData.FieldCount > 0) then
|
||||||
|
//if (FCurrentResData.FieldCount = 1) then
|
||||||
|
FCurrentResData := FCurrentResData.Fields[0].Field;
|
||||||
|
|
||||||
|
if (FCurrentResData.FieldCount > 1) and
|
||||||
|
( (FCurrentResData.Fields[0].Field = nil) or
|
||||||
|
(FCurrentResData.Fields[0].Field.ValueKind = rdkError)
|
||||||
|
)
|
||||||
|
then
|
||||||
|
FCurrentResData := FCurrentResData.Fields[1].Field;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
ArrayNavigationBar1.Visible := FCurrentResData.ValueKind = rdkArray;
|
||||||
|
case FCurrentResData.ValueKind of
|
||||||
//rdkError: ;
|
//rdkError: ;
|
||||||
rdkPrePrinted,
|
rdkPrePrinted,
|
||||||
rdkString,
|
rdkString,
|
||||||
@ -1425,6 +1448,7 @@ begin
|
|||||||
if (not btnPower.Down) or (not Visible) then exit;
|
if (not btnPower.Down) or (not Visible) then exit;
|
||||||
if (ADebugger.State = dsPause) and (AnOldState <> dsPause) then begin
|
if (ADebugger.State = dsPause) and (AnOldState <> dsPause) then begin
|
||||||
ReleaseRefAndNil(FCurrentWatchValue);
|
ReleaseRefAndNil(FCurrentWatchValue);
|
||||||
|
FCurrentResData := nil;
|
||||||
FInspectWatches.Clear;
|
FInspectWatches.Clear;
|
||||||
UpdateData;
|
UpdateData;
|
||||||
end;
|
end;
|
||||||
@ -1440,6 +1464,7 @@ procedure TIDEInspectDlg.DoWatchesInvalidated(Sender: TObject);
|
|||||||
begin
|
begin
|
||||||
if (not btnPower.Down) or (not Visible) then exit;
|
if (not btnPower.Down) or (not Visible) then exit;
|
||||||
ReleaseRefAndNil(FCurrentWatchValue);
|
ReleaseRefAndNil(FCurrentWatchValue);
|
||||||
|
FCurrentResData := nil;
|
||||||
FInspectWatches.Clear;
|
FInspectWatches.Clear;
|
||||||
UpdateData;
|
UpdateData;
|
||||||
end;
|
end;
|
||||||
@ -1459,6 +1484,7 @@ begin
|
|||||||
expr := trim(FExpression);
|
expr := trim(FExpression);
|
||||||
if expr = '' then begin
|
if expr = '' then begin
|
||||||
ReleaseRefAndNil(FCurrentWatchValue);
|
ReleaseRefAndNil(FCurrentWatchValue);
|
||||||
|
FCurrentResData := nil;
|
||||||
Clear;
|
Clear;
|
||||||
StatusBar1.SimpleText := '';
|
StatusBar1.SimpleText := '';
|
||||||
exit;
|
exit;
|
||||||
@ -1496,6 +1522,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
ReleaseRefAndNil(FCurrentWatchValue);
|
ReleaseRefAndNil(FCurrentWatchValue);
|
||||||
|
FCurrentResData := nil;
|
||||||
|
|
||||||
FInspectWatches.BeginUpdate;
|
FInspectWatches.BeginUpdate;
|
||||||
AWatch := FInspectWatches.Find(expr);
|
AWatch := FInspectWatches.Find(expr);
|
||||||
@ -1510,6 +1537,7 @@ begin
|
|||||||
FInspectWatches.EndUpdate;
|
FInspectWatches.EndUpdate;
|
||||||
FCurrentWatchValue := AWatch.Values[tid, idx];
|
FCurrentWatchValue := AWatch.Values[tid, idx];
|
||||||
if FCurrentWatchValue <> nil then begin
|
if FCurrentWatchValue <> nil then begin
|
||||||
|
FCurrentResData := FCurrentWatchValue.ResultData;
|
||||||
FCurrentWatchValue.AddReference;
|
FCurrentWatchValue.AddReference;
|
||||||
FCurrentWatchValue.Value;
|
FCurrentWatchValue.Value;
|
||||||
end;
|
end;
|
||||||
|
@ -1276,7 +1276,8 @@ begin
|
|||||||
|
|
||||||
HasChildren := ( (TypInfo <> nil) and (TypInfo.Fields <> nil) and (TypInfo.Fields.Count > 0) ) or
|
HasChildren := ( (TypInfo <> nil) and (TypInfo.Fields <> nil) and (TypInfo.Fields.Count > 0) ) or
|
||||||
( (WatchValue.ResultData <> nil) and
|
( (WatchValue.ResultData <> nil) and
|
||||||
( (WatchValue.ResultData.FieldCount > 0) or
|
( ( (WatchValue.ResultData.FieldCount > 0) and (WatchValue.ResultData.StructType <> dstInternal) )
|
||||||
|
or
|
||||||
( (WatchValue.ResultData.ValueKind = rdkArray) and (WatchValue.ResultData.ArrayLength > 0) )
|
( (WatchValue.ResultData.ValueKind = rdkArray) and (WatchValue.ResultData.ArrayLength > 0) )
|
||||||
) );
|
) );
|
||||||
tvWatches.HasChildren[VNode] := HasChildren;
|
tvWatches.HasChildren[VNode] := HasChildren;
|
||||||
@ -1413,7 +1414,9 @@ var
|
|||||||
begin
|
begin
|
||||||
ChildCount := 0;
|
ChildCount := 0;
|
||||||
|
|
||||||
if (AWatchValue.ResultData <> nil) and (AWatchValue.ResultData.FieldCount > 0) then begin
|
if (AWatchValue.ResultData <> nil) and (AWatchValue.ResultData.FieldCount > 0) and
|
||||||
|
(AWatchValue.ResultData.StructType <> dstInternal)
|
||||||
|
then begin
|
||||||
ResData := AWatchValue.ResultData;
|
ResData := AWatchValue.ResultData;
|
||||||
ChildCount := ResData.FieldCount;
|
ChildCount := ResData.FieldCount;
|
||||||
AWatch := AWatchValue.Watch;
|
AWatch := AWatchValue.Watch;
|
||||||
|
@ -142,6 +142,32 @@ var
|
|||||||
begin
|
begin
|
||||||
Result := '';
|
Result := '';
|
||||||
|
|
||||||
|
if (AResValue.ValueKind = rdkStruct) and
|
||||||
|
(AResValue.StructType = dstInternal)
|
||||||
|
then begin
|
||||||
|
if AResValue.FieldCount = 0 then
|
||||||
|
exit('Error: No result');
|
||||||
|
|
||||||
|
if (AResValue.FieldCount = 1) or
|
||||||
|
( (AResValue.Fields[0].Field <> nil) and
|
||||||
|
((AResValue.Fields[0].Field.ValueKind <> rdkError))
|
||||||
|
)
|
||||||
|
then begin
|
||||||
|
Result := PrintWatchValueEx(AResValue.Fields[0].Field, ADispFormat, ANestLvl);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if (AResValue.FieldCount > 1) then begin
|
||||||
|
Result := PrintWatchValueEx(AResValue.Fields[1].Field, ADispFormat, ANestLvl);
|
||||||
|
Result := Result + ' { '
|
||||||
|
+ PrintWatchValueEx(AResValue.Fields[0].Field, ADispFormat, ANestLvl)
|
||||||
|
+ ' }';
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
exit('Error: No result');
|
||||||
|
end;
|
||||||
|
|
||||||
if (AResValue.StructType in [dstClass, dstInterface])
|
if (AResValue.StructType in [dstClass, dstInterface])
|
||||||
then begin
|
then begin
|
||||||
tn := AResValue.TypeName;
|
tn := AResValue.TypeName;
|
||||||
|
Loading…
Reference in New Issue
Block a user