Debuggers (FpLLDB, FpGDBMI): add some safety checks. Do not free dwarf, in the middle of watch eval

git-svn-id: trunk@63786 -
This commit is contained in:
martin 2020-08-18 23:12:49 +00:00
parent d8007187b8
commit 35d829c943
2 changed files with 85 additions and 28 deletions

View File

@ -76,6 +76,8 @@ type
FMemManager: TFpDbgMemManager;
// cache last context
FLastContext: array [0..MAX_CTX_CACHE-1] of TFpDbgSymbolScope;
FLockUnLoadDwarf: integer;
FUnLoadDwarfNeeded: Boolean;
protected
function CreateCommandStartDebugging(AContinueCommand: TGDBMIDebuggerCommand): TGDBMIDebuggerCommandStartDebugging; override;
function CreateLineInfo: TDBGLineInfo; override;
@ -85,6 +87,8 @@ type
function HasDwarf: Boolean;
procedure LoadDwarf;
procedure UnLoadDwarf;
procedure LockUnLoadDwarf;
procedure UnLockUnLoadDwarf;
function RequestCommand(const ACommand: TDBGCommand;
const AParams: array of const;
const ACallback: TMethod): Boolean; override;
@ -276,36 +280,41 @@ var
m: TFpValue;
n, v: String;
begin
Ctx := FpDebugger.GetInfoContextForContext(ALocals.ThreadId, ALocals.StackFrame);
if (Ctx = nil) or (Ctx.SymbolAtAddress = nil) then begin
ALocals.SetDataValidity(ddsInvalid);
exit;
end;
ProcVal := Ctx.ProcedureAtAddress;
if (ProcVal = nil) then begin
ALocals.SetDataValidity(ddsInvalid);
exit;
end;
FpDebugger.FPrettyPrinter.AddressSize := ctx.SizeOfAddress;
FpDebugger.FPrettyPrinter.MemManager := ctx.MemManager;
ALocals.Clear;
for i := 0 to ProcVal.MemberCount - 1 do begin
m := ProcVal.Member[i];
if m <> nil then begin
if m.DbgSymbol <> nil then
n := m.DbgSymbol.Name
else
n := '';
FpDebugger.FPrettyPrinter.PrintValue(v, m);
m.ReleaseReference;
ALocals.Add(n, v);
FpDebugger.LockUnLoadDwarf;
try
Ctx := FpDebugger.GetInfoContextForContext(ALocals.ThreadId, ALocals.StackFrame);
if (Ctx = nil) or (Ctx.SymbolAtAddress = nil) then begin
ALocals.SetDataValidity(ddsInvalid);
exit;
end;
ProcVal := Ctx.ProcedureAtAddress;
if (ProcVal = nil) then begin
ALocals.SetDataValidity(ddsInvalid);
exit;
end;
FpDebugger.FPrettyPrinter.AddressSize := ctx.SizeOfAddress;
FpDebugger.FPrettyPrinter.MemManager := ctx.MemManager;
ALocals.Clear;
for i := 0 to ProcVal.MemberCount - 1 do begin
m := ProcVal.Member[i];
if m <> nil then begin
if m.DbgSymbol <> nil then
n := m.DbgSymbol.Name
else
n := '';
FpDebugger.FPrettyPrinter.PrintValue(v, m);
m.ReleaseReference;
ALocals.Add(n, v);
end;
end;
ProcVal.ReleaseReference;
ALocals.SetDataValidity(ddsValid);
finally
FpDebugger.UnLockUnLoadDwarf;
end;
ProcVal.ReleaseReference;
ALocals.SetDataValidity(ddsValid);
end;
function TFPGDBMILocals.FpDebugger: TFpGDBMIDebugger;
@ -569,6 +578,7 @@ begin
if FWatchEvalLock > 0 then
exit;
inc(FWatchEvalLock);
FpDebugger.LockUnLoadDwarf;
try // TODO: if the stack/thread is changed, registers will be wrong
while (FpDebugger.FWatchEvalList.Count > 0) and (FEvaluationCmdObj = nil) do begin
try
@ -598,6 +608,7 @@ begin
end;
finally
dec(FWatchEvalLock);
FpDebugger.UnLockUnLoadDwarf;
end;
end;
@ -777,6 +788,11 @@ end;
procedure TFpGDBMIDebugger.UnLoadDwarf;
begin
if FLockUnLoadDwarf > 0 then begin
FUnLoadDwarfNeeded := True;
exit;
end;
FUnLoadDwarfNeeded := False;
debugln(DBG_VERBOSE, ['TFpGDBMIDebugger.UnLoadDwarf ']);
FreeAndNil(FDwarfInfo);
FreeAndNil(FImageLoaderList);
@ -787,6 +803,18 @@ begin
FreeAndNil(FPrettyPrinter);
end;
procedure TFpGDBMIDebugger.LockUnLoadDwarf;
begin
inc(FLockUnLoadDwarf);
end;
procedure TFpGDBMIDebugger.UnLockUnLoadDwarf;
begin
dec(FLockUnLoadDwarf);
if (FLockUnLoadDwarf <= 0) and FUnLoadDwarfNeeded then
UnLoadDwarf;
end;
function TFpGDBMIDebugger.RequestCommand(const ACommand: TDBGCommand;
const AParams: array of const; const ACallback: TMethod): Boolean;
var
@ -1030,6 +1058,7 @@ begin
FPrettyPrinter.AddressSize := ctx.SizeOfAddress;
FPrettyPrinter.MemManager := ctx.MemManager;
LockUnLoadDwarf;
PasExpr := TFpPascalExpression.Create(AExpression, Ctx);
try
if not IsWatchValueAlive then exit;
@ -1130,6 +1159,7 @@ DebugLn(DBG_VERBOSE, [ErrorHandler.ErrorAsString(PasExpr.Error)]);
finally
PasExpr.Free;
FMemManager.DefaultContext := nil;
UnLockUnLoadDwarf;
end;
end;

View File

@ -131,6 +131,8 @@ type
FDwarfLoaderThread: TDwarfLoaderThread;
// cache last context
FLastContext: array [0..MAX_CTX_CACHE-1] of TFpDbgSymbolScope;
FLockUnLoadDwarf: integer;
FUnLoadDwarfNeeded: Boolean;
procedure DoBeginReceivingLines(Sender: TObject);
procedure DoEndReceivingLines(Sender: TObject);
protected
@ -144,6 +146,8 @@ type
function HasDwarf: Boolean;
function LoadDwarf: String;
procedure UnLoadDwarf;
procedure LockUnLoadDwarf;
procedure UnLockUnLoadDwarf;
function RequestCommand(const ACommand: TDBGCommand;
const AParams: array of const;
const ACallback: TMethod): Boolean; override;
@ -412,6 +416,7 @@ begin
exit;
end;
FpDebugger.LockUnLoadDwarf;
Ctx := FpDebugger.GetInfoContextForContext(ALocals.ThreadId, ALocals.StackFrame);
try
if (Ctx = nil) or (Ctx.SymbolAtAddress = nil) then begin
@ -449,6 +454,7 @@ begin
finally
Ctx.ReleaseReference;
ProcVal.ReleaseReference;
FpDebugger.UnLockUnLoadDwarf;
end;
end;
@ -799,6 +805,7 @@ begin
debugln(['ProcessEvalList ']);
inc(FWatchEvalLock);
FpDebugger.LockUnLoadDwarf;
try // TODO: if the stack/thread is changed, registers will be wrong
while (FpDebugger.FWatchEvalList.Count > 0) and (FEvaluationCmdObj = nil) and (not FWatchEvalCancel)
do begin
@ -828,6 +835,7 @@ debugln(['ProcessEvalList ']);
end;
finally
dec(FWatchEvalLock);
FpDebugger.UnLockUnLoadDwarf;
end;
end;
@ -1208,6 +1216,11 @@ end;
procedure TFpLldbDebugger.UnLoadDwarf;
begin
if FLockUnLoadDwarf > 0 then begin
FUnLoadDwarfNeeded := True;
exit;
end;
FUnLoadDwarfNeeded := False;
debugln(DBG_VERBOSE, ['TFpLldbDebugger.UnLoadDwarf ']);
FreeAndNil(FDwarfInfo);
FreeAndNil(FImageLoaderList);
@ -1226,6 +1239,18 @@ begin
end;
end;
procedure TFpLldbDebugger.LockUnLoadDwarf;
begin
inc(FLockUnLoadDwarf);
end;
procedure TFpLldbDebugger.UnLockUnLoadDwarf;
begin
dec(FLockUnLoadDwarf);
if (FLockUnLoadDwarf <= 0) and FUnLoadDwarfNeeded then
UnLoadDwarf;
end;
function TFpLldbDebugger.RequestCommand(const ACommand: TDBGCommand;
const AParams: array of const; const ACallback: TMethod): Boolean;
var
@ -1473,6 +1498,7 @@ begin
FPrettyPrinter.AddressSize := ctx.SizeOfAddress;
FPrettyPrinter.MemManager := ctx.MemManager;
LockUnLoadDwarf;
PasExpr := TFpPascalExpression.Create(AExpression, Ctx);
try
if not IsWatchValueAlive then exit;
@ -1591,6 +1617,7 @@ DebugLn(DBG_VERBOSE, [ErrorHandler.ErrorAsString(PasExpr.Error)]);
PasExpr.Free;
FMemManager.DefaultContext := nil;
Ctx.ReleaseReference;
UnLockUnLoadDwarf;
end;
end;