LazDebuggerFp: Handle WatchValue in thread

This commit is contained in:
Martin 2022-01-30 12:40:19 +01:00
parent 9de06ac372
commit 442f57cf49
2 changed files with 42 additions and 36 deletions

View File

@ -134,8 +134,7 @@ type
TFpThreadWorkerWatchValueEvalUpdate = class(TFpThreadWorkerWatchValueEval) TFpThreadWorkerWatchValueEvalUpdate = class(TFpThreadWorkerWatchValueEval)
private private
FWatchValue: TWatchValueIntf; procedure DoWachCanceled(Sender: TObject);
procedure DoWatchFreed_DecRef(Sender: TObject);
protected protected
procedure UpdateWatch_DecRef(Data: PtrInt = 0); override; procedure UpdateWatch_DecRef(Data: PtrInt = 0); override;
procedure DoRemovedFromLinkedList; override; // _DecRef procedure DoRemovedFromLinkedList; override; // _DecRef
@ -1013,13 +1012,14 @@ end;
{ TFpThreadWorkerWatchValueEvalUpdate } { TFpThreadWorkerWatchValueEvalUpdate }
procedure TFpThreadWorkerWatchValueEvalUpdate.DoWatchFreed_DecRef( procedure TFpThreadWorkerWatchValueEvalUpdate.DoWachCanceled(Sender: TObject);
Sender: TObject);
begin begin
assert(system.ThreadID = classes.MainThreadID, 'TFpThreadWorkerWatchValueEval.DoWatchFreed_DecRef: system.ThreadID = classes.MainThreadID'); assert(system.ThreadID = classes.MainThreadID, 'TFpThreadWorkerWatchValueEvalUpdate.DoWachCanceled: system.ThreadID = classes.MainThreadID');
FWatchValue := nil;
RequestStop; RequestStop;
UnQueue_DecRef; UnQueue_DecRef;
if IsCancelled then begin
///
end;
end; end;
procedure TFpThreadWorkerWatchValueEvalUpdate.UpdateWatch_DecRef(Data: PtrInt); procedure TFpThreadWorkerWatchValueEvalUpdate.UpdateWatch_DecRef(Data: PtrInt);
@ -1029,20 +1029,8 @@ begin
assert(system.ThreadID = classes.MainThreadID, 'TFpThreadWorkerWatchValueEval.UpdateWatch_DecRef: system.ThreadID = classes.MainThreadID'); assert(system.ThreadID = classes.MainThreadID, 'TFpThreadWorkerWatchValueEval.UpdateWatch_DecRef: system.ThreadID = classes.MainThreadID');
if FWatchValue <> nil then begin if FWatchValue <> nil then begin
FWatchValue.RemoveFreeNotification(@DoWatchFreed_DecRef); FWatchValue.RemoveNotification(weeCancel, @DoWachCanceled);
FWatchValue.EndUpdate;
FWatchValue.Value := FResText;
FWatchValue.TypeInfo := FResDbgType;
if not FRes then begin
if FResText = '' then
FWatchValue.Validity := ddsInvalid
else
FWatchValue.Validity := ddsError;
end
else begin
FWatchValue.Validity := ddsValid;
end;
FWatchValue := nil; FWatchValue := nil;
end; end;
@ -1054,20 +1042,13 @@ end;
procedure TFpThreadWorkerWatchValueEvalUpdate.DoRemovedFromLinkedList; procedure TFpThreadWorkerWatchValueEvalUpdate.DoRemovedFromLinkedList;
begin begin
if FWatchValue <> nil then begin if FWatchValue <> nil then begin
FWatchValue.RemoveFreeNotification(@DoWatchFreed_DecRef); FWatchValue.RemoveNotification(weeCancel, @DoWachCanceled);
if FRes then begin if FWatchValue.Validity = ddsRequested then
UpdateWatch_DecRef; FWatchValue.Validity := ddsInvalid;
end FWatchValue.EndUpdate;
else begin
FWatchValue.Validity := ddsInvalid;
FWatchValue := nil;
UnQueue_DecRef;
end;
end
else begin
UnQueue_DecRef;
FWatchValue := nil; FWatchValue := nil;
end; end;
UnQueue_DecRef;
end; end;
constructor TFpThreadWorkerWatchValueEvalUpdate.Create( constructor TFpThreadWorkerWatchValueEvalUpdate.Create(
@ -1075,7 +1056,9 @@ constructor TFpThreadWorkerWatchValueEvalUpdate.Create(
begin begin
assert(system.ThreadID = classes.MainThreadID, 'TFpThreadWorkerWatchValueEval.Create: system.ThreadID = classes.MainThreadID'); assert(system.ThreadID = classes.MainThreadID, 'TFpThreadWorkerWatchValueEval.Create: system.ThreadID = classes.MainThreadID');
FWatchValue := AWatchValue; FWatchValue := AWatchValue;
FWatchValue.AddFreeNotification(@DoWatchFreed_DecRef); FWatchValue.BeginUpdate;
FWatchValue.AddNotification(weeCancel, @DoWachCanceled);
inherited Create(ADebugger, twpWatch, FWatchValue.Expression, FWatchValue.StackFrame, FWatchValue.ThreadId, inherited Create(ADebugger, twpWatch, FWatchValue.Expression, FWatchValue.StackFrame, FWatchValue.ThreadId,
FWatchValue.DisplayFormat, FWatchValue.RepeatCount, FWatchValue.EvaluateFlags); FWatchValue.DisplayFormat, FWatchValue.RepeatCount, FWatchValue.EvaluateFlags);
end; end;

View File

@ -241,6 +241,7 @@ type
AFunctionValue, ASelfValue: TFpValue; AParams: TFpPascalExpressionPartList; AFunctionValue, ASelfValue: TFpValue; AParams: TFpPascalExpressionPartList;
out AResult: TFpValue; var AnError: TFpError): boolean; out AResult: TFpValue; var AnError: TFpError): boolean;
protected protected
FWatchValue: TWatchValueIntf;
function EvaluateExpression(const AnExpression: String; function EvaluateExpression(const AnExpression: String;
AStackFrame, AThreadId: Integer; AStackFrame, AThreadId: Integer;
ADispFormat: TWatchDisplayFormat; ADispFormat: TWatchDisplayFormat;
@ -956,8 +957,11 @@ begin
ATypeInfo := nil; ATypeInfo := nil;
FExpressionScope := FDebugger.FDbgController.CurrentProcess.FindSymbolScope(AThreadId, AStackFrame); FExpressionScope := FDebugger.FDbgController.CurrentProcess.FindSymbolScope(AThreadId, AStackFrame);
if FExpressionScope = nil then if FExpressionScope = nil then begin
if FWatchValue <> nil then
FWatchValue.Validity := ddsInvalid;
exit; exit;
end;
PrettyPrinter := nil; PrettyPrinter := nil;
APasExpr := TFpPascalExpression.Create(AnExpression, FExpressionScope); APasExpr := TFpPascalExpression.Create(AnExpression, FExpressionScope);
@ -967,17 +971,28 @@ begin
APasExpr.ResultValue; // trigger full validation APasExpr.ResultValue; // trigger full validation
if not APasExpr.Valid then begin if not APasExpr.Valid then begin
AResText := ErrorHandler.ErrorAsString(APasExpr.Error); AResText := ErrorHandler.ErrorAsString(APasExpr.Error);
if FWatchValue <> nil then begin
FWatchValue.Value := AResText;
FWatchValue.Validity := ddsError;
end;
exit; exit;
end; end;
ResValue := APasExpr.ResultValue; ResValue := APasExpr.ResultValue;
if ResValue = nil then begin if ResValue = nil then begin
AResText := 'Error'; AResText := 'Error';
if FWatchValue <> nil then begin
FWatchValue.Value := AResText;
FWatchValue.Validity := ddsError;
end;
exit; exit;
end; end;
if StopRequested then if StopRequested then begin
if FWatchValue <> nil then
FWatchValue.Validity := ddsInvalid;
exit; exit;
end;
if (ResValue.Kind = skClass) and (ResValue.AsCardinal <> 0) and if (ResValue.Kind = skClass) and (ResValue.AsCardinal <> 0) and
(not IsError(ResValue.LastError)) and (defClassAutoCast in AnEvalFlags) (not IsError(ResValue.LastError)) and (defClassAutoCast in AnEvalFlags)
then begin then begin
@ -998,8 +1013,11 @@ begin
end; end;
end; end;
if StopRequested then if StopRequested then begin
if FWatchValue <> nil then
FWatchValue.Validity := ddsInvalid;
exit; exit;
end;
PrettyPrinter := TFpPascalPrettyPrinter.Create(FExpressionScope.SizeOfAddress); PrettyPrinter := TFpPascalPrettyPrinter.Create(FExpressionScope.SizeOfAddress);
PrettyPrinter.Context := FExpressionScope.LocationContext; PrettyPrinter.Context := FExpressionScope.LocationContext;
@ -1027,6 +1045,11 @@ begin
if not Result then if not Result then
FreeAndNil(ATypeInfo); FreeAndNil(ATypeInfo);
if FWatchValue <> nil then begin
FWatchValue.Value := AResText;
FWatchValue.TypeInfo := ATypeInfo;
FWatchValue.Validity := ddsValid;
end;
finally finally
PrettyPrinter.Free; PrettyPrinter.Free;
APasExpr.Free; APasExpr.Free;