mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-22 13:59:22 +02:00
FpDebug: Workaround for dangling thread object
git-svn-id: trunk@59551 -
This commit is contained in:
parent
df5a68e852
commit
84e5ae329a
@ -739,6 +739,8 @@ var
|
|||||||
IsHandled: boolean;
|
IsHandled: boolean;
|
||||||
IsFinished: boolean;
|
IsFinished: boolean;
|
||||||
EventProcess: TDbgProcess;
|
EventProcess: TDbgProcess;
|
||||||
|
DummyThread: TDbgThread;
|
||||||
|
ctid: Integer;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
AExit:=false;
|
AExit:=false;
|
||||||
@ -747,6 +749,9 @@ begin
|
|||||||
FMainProcess:=FCurrentProcess
|
FMainProcess:=FCurrentProcess
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
|
ctid := 0;
|
||||||
|
if FCurrentThread <> nil then
|
||||||
|
ctid := FCurrentThread.ID;
|
||||||
if not assigned(FCommand) then
|
if not assigned(FCommand) then
|
||||||
begin
|
begin
|
||||||
{$ifdef DBG_FPDEBUG_VERBOSE}
|
{$ifdef DBG_FPDEBUG_VERBOSE}
|
||||||
@ -761,6 +766,11 @@ begin
|
|||||||
{$endif DBG_FPDEBUG_VERBOSE}
|
{$endif DBG_FPDEBUG_VERBOSE}
|
||||||
FCommand.DoContinue(FCurrentProcess, FCurrentThread);
|
FCommand.DoContinue(FCurrentProcess, FCurrentThread);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
// TODO: replace the dangling pointer with the next best value....
|
||||||
|
// There is still a race condition, for another thread to access it...
|
||||||
|
if (ctid <> 0) and not FCurrentProcess.GetThread(ctid, DummyThread) then
|
||||||
|
FCurrentThread := nil;
|
||||||
end;
|
end;
|
||||||
if not FCurrentProcess.WaitForDebugEvent(AProcessIdentifier, AThreadIdentifier) then Continue;
|
if not FCurrentProcess.WaitForDebugEvent(AProcessIdentifier, AThreadIdentifier) then Continue;
|
||||||
|
|
||||||
@ -771,6 +781,11 @@ begin
|
|||||||
and if it were debugged, *all* debugged processes may need to be paused)
|
and if it were debugged, *all* debugged processes may need to be paused)
|
||||||
- The LazFpDebugger may try to access FCurrentThread. If that is nil, it may crash.
|
- The LazFpDebugger may try to access FCurrentThread. If that is nil, it may crash.
|
||||||
e.g. TFPThreads.RequestMasterData
|
e.g. TFPThreads.RequestMasterData
|
||||||
|
|
||||||
|
This may need 3 threads: main, user-selected (thread win), current-event
|
||||||
|
|
||||||
|
deExitProcess relies on only the main process receiving this.
|
||||||
|
|
||||||
*)
|
*)
|
||||||
//FCurrentProcess := nil;
|
//FCurrentProcess := nil;
|
||||||
//FCurrentThread := nil;
|
//FCurrentThread := nil;
|
||||||
@ -791,7 +806,8 @@ begin
|
|||||||
*)
|
*)
|
||||||
//FCurrentProcess := OSDbgClasses.DbgProcessClass.Create('', AProcessIdentifier, AThreadIdentifier, OnLog);
|
//FCurrentProcess := OSDbgClasses.DbgProcessClass.Create('', AProcessIdentifier, AThreadIdentifier, OnLog);
|
||||||
//FProcessMap.Add(AProcessIdentifier, FCurrentProcess);
|
//FProcessMap.Add(AProcessIdentifier, FCurrentProcess);
|
||||||
Continue;
|
|
||||||
|
Continue; // ***** This will swallow all FPDEvent for unknow processes *****
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if EventProcess<>FMainProcess then
|
if EventProcess<>FMainProcess then
|
||||||
@ -802,6 +818,11 @@ begin
|
|||||||
if not FCurrentProcess.GetThread(AThreadIdentifier, FCurrentThread) then
|
if not FCurrentProcess.GetThread(AThreadIdentifier, FCurrentThread) then
|
||||||
FCurrentThread := FCurrentProcess.AddThread(AThreadIdentifier);
|
FCurrentThread := FCurrentProcess.AddThread(AThreadIdentifier);
|
||||||
|
|
||||||
|
(* TODO: ExitThread **********
|
||||||
|
at least the winprocess handles exitthread in the next line.
|
||||||
|
this will remove CurrentThread form the list of threads
|
||||||
|
CurrentThread is then destroyed in the next call to continue....
|
||||||
|
*)
|
||||||
FPDEvent:=FCurrentProcess.ResolveDebugEvent(FCurrentThread);
|
FPDEvent:=FCurrentProcess.ResolveDebugEvent(FCurrentThread);
|
||||||
{$ifdef DBG_FPDEBUG_VERBOSE}
|
{$ifdef DBG_FPDEBUG_VERBOSE}
|
||||||
log('Process stopped with event %s. IP=%s, SP=%s, BSP=%s.', [FPDEventNames[FPDEvent],
|
log('Process stopped with event %s. IP=%s, SP=%s, BSP=%s.', [FPDEventNames[FPDEvent],
|
||||||
@ -854,6 +875,7 @@ begin
|
|||||||
case FPDEvent of
|
case FPDEvent of
|
||||||
deCreateProcess:
|
deCreateProcess:
|
||||||
begin
|
begin
|
||||||
|
(* Only events for the main process get here / See ProcessLoop *)
|
||||||
FCurrentProcess.LoadInfo;
|
FCurrentProcess.LoadInfo;
|
||||||
if not FCurrentProcess.DbgInfo.HasInfo then
|
if not FCurrentProcess.DbgInfo.HasInfo then
|
||||||
Log('No Dwarf-debug information available. The debugger will not function properly. [CurrentProcess='+dbgsname(FCurrentProcess)+',DbgInfo='+dbgsname(FCurrentProcess.DbgInfo)+']',dllInfo);
|
Log('No Dwarf-debug information available. The debugger will not function properly. [CurrentProcess='+dbgsname(FCurrentProcess)+',DbgInfo='+dbgsname(FCurrentProcess.DbgInfo)+']',dllInfo);
|
||||||
@ -872,6 +894,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
deExitProcess:
|
deExitProcess:
|
||||||
begin
|
begin
|
||||||
|
(* Only events for the main process get here / See ProcessLoop *)
|
||||||
if FCurrentProcess = FMainProcess then FMainProcess := nil;
|
if FCurrentProcess = FMainProcess then FMainProcess := nil;
|
||||||
|
|
||||||
if assigned(OnProcessExitEvent) then
|
if assigned(OnProcessExitEvent) then
|
||||||
|
@ -447,6 +447,9 @@ begin
|
|||||||
Result := False;
|
Result := False;
|
||||||
case ADebugEvent.dwDebugEventCode of
|
case ADebugEvent.dwDebugEventCode of
|
||||||
EXIT_THREAD_DEBUG_EVENT: begin
|
EXIT_THREAD_DEBUG_EVENT: begin
|
||||||
|
// The thread event will be freed later, may still be used
|
||||||
|
// will be freed, in "TDbgWinProcess.Continue"
|
||||||
|
// This relies on the thread being removed, to be the same as FCurrentThread in FPDbgController
|
||||||
RemoveThread(ADebugEvent.dwThreadId);
|
RemoveThread(ADebugEvent.dwThreadId);
|
||||||
end;
|
end;
|
||||||
LOAD_DLL_DEBUG_EVENT: begin
|
LOAD_DLL_DEBUG_EVENT: begin
|
||||||
|
@ -401,7 +401,10 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
CurrentThreads.CurrentThreadId := TFpDebugDebugger(Debugger).FDbgController.CurrentThread.ID;
|
if TFpDebugDebugger(Debugger).FDbgController.CurrentThread = nil then
|
||||||
|
CurrentThreads.CurrentThreadId := 0 // TODO: only until controller is guranteed to have a currentthread
|
||||||
|
else
|
||||||
|
CurrentThreads.CurrentThreadId := TFpDebugDebugger(Debugger).FDbgController.CurrentThread.ID;
|
||||||
CurrentThreads.SetValidity(ddsValid);
|
CurrentThreads.SetValidity(ddsValid);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user