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

View File

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