From cc86c3c99e42653333de42916a302df2944ea03c Mon Sep 17 00:00:00 2001 From: martin Date: Mon, 15 Nov 2010 21:51:24 +0000 Subject: [PATCH] DBG: Assembler-View: Fixed crash after resting (destroy) debugger git-svn-id: trunk@28255 - --- debugger/assemblerdlg.pp | 37 ++++++++++++++++++++++++++++--------- debugger/debugger.pp | 23 +++++++++++++++++++++++ 2 files changed, 51 insertions(+), 9 deletions(-) diff --git a/debugger/assemblerdlg.pp b/debugger/assemblerdlg.pp index 3f281a04d8..16478ea28b 100644 --- a/debugger/assemblerdlg.pp +++ b/debugger/assemblerdlg.pp @@ -72,6 +72,7 @@ type FGutterWidth: Integer; FUpdating: Boolean; FUpdateNeeded: Boolean; + procedure DoDebuggerDestroyed(Sender: TObject); procedure ClearLineMap(AState: TAsmDlgLineMapState = lmsUnknown); procedure DisassemblerChanged(Sender: TObject); procedure SetDisassembler(const AValue: TIDEDisassembler); @@ -224,14 +225,15 @@ procedure TAssemblerDlg.DisassemblerChanged(Sender: TObject); begin if (FDisassembler = nil) or (FLocation = 0) or (FLineCount = 0) then exit; - if FDebugger.State <> dsPause + if (FDebugger <> nil) and (FDebugger.State <> dsPause) then begin // only for F9, not for F8,F7 single stepping with assembler is no good, if it clears all the time //ClearLineMap; end else begin // Check if anything is there, update BaseAddr - FDisassembler.PrepareRange(FLocation, Max(0, -(FTopLine - 5)), Max(0, FTopLine + FLineCount + 1 + 5)); + if FDisassembler <> nil + then FDisassembler.PrepareRange(FLocation, Max(0, -(FTopLine - 5)), Max(0, FTopLine + FLineCount + 1 + 5)); UpdateLineData; end; pbAsm.Invalidate; @@ -428,9 +430,24 @@ begin end; end; +procedure TAssemblerDlg.DoDebuggerDestroyed(Sender: TObject); +begin + FDebugger := nil; + FDisassembler := nil; + UpdateLineData; + pbAsm.Invalidate; +end; + procedure TAssemblerDlg.SetLocation(ADebugger: TDebugger; const AAddr: TDBGPtr); begin - FDebugger := ADebugger; + if FDebugger <> ADebugger + then begin + if FDebugger <> nil + then FDebugger.RemoveNotifyEvent(dnrDestroy, @DoDebuggerDestroyed); + FDebugger := ADebugger; + if FDebugger <> nil + then FDebugger.AddNotifyEvent(dnrDestroy, @DoDebuggerDestroyed); + end; FTopLine := -(FLineCount div 2); FSelectLine := 0; FSelectionEndLine := 0; @@ -439,7 +456,8 @@ begin if Visible then begin // otherwhise in resize - FDisassembler.PrepareRange(FLocation, Max(0, -(FTopLine - 5)), Max(0, FTopLine + FLineCount + 1 + 5)); + if FDisassembler <> nil + then FDisassembler.PrepareRange(FLocation, Max(0, -(FTopLine - 5)), Max(0, FTopLine + FLineCount + 1 + 5)); UpdateLineData; pbAsm.Invalidate; end @@ -486,7 +504,8 @@ begin SetLength(FLineMap, FLineCount + 1); if FLocation <> 0 then begin - FDisassembler.PrepareRange(FLocation, Max(0, -(FTopLine - 5)), Max(0, FTopLine + FLineCount + 1 + 5)); + if FDisassembler <> nil + then FDisassembler.PrepareRange(FLocation, Max(0, -(FTopLine - 5)), Max(0, FTopLine + FLineCount + 1 + 5)); UpdateLineData; end; pbAsm.Invalidate; @@ -504,8 +523,9 @@ begin then PadFront := 25 else PadEnd := 25; FTopLine := ALine; - if (FDisassembler.CountBefore < Max(0, -(FTopLine - PadFront))) - or (FDisassembler.CountAfter < Max(0, FTopLine + FLineCount + 1 + PadEnd)) + if (FDisassembler <> nil) + and ( (FDisassembler.CountBefore < Max(0, -(FTopLine - PadFront))) + or (FDisassembler.CountAfter < Max(0, FTopLine + FLineCount + 1 + PadEnd)) ) then FDisassembler.PrepareRange(FLocation, Max(0, -(FTopLine - PadFront)), Max(0, FTopLine + FLineCount + 1 + PadEnd)); UpdateLineData; end; @@ -554,8 +574,7 @@ var Itm, NextItm: PDisassemblerEntry; LineIsSrc, HasLineOutOfRange: Boolean; begin - if FDebugger = nil then Exit; - If FDebugger.State <> dsPause + if (FDebugger = nil) or (FDisassembler = nil) or (FDebugger.State <> dsPause) then begin ClearLineMap; // set all to lmsUnknown; exit; diff --git a/debugger/debugger.pp b/debugger/debugger.pp index 027fdaaebe..b27631ef00 100644 --- a/debugger/debugger.pp +++ b/debugger/debugger.pp @@ -1431,6 +1431,8 @@ type const AExceptionText: String; out AContinue: Boolean) of object; + TDebuggerNotifyReason = (dnrDestroy); + TDebuggerProperties = class(TPersistent) private public @@ -1466,6 +1468,7 @@ type FOnState: TDebuggerStateChangedEvent; FOnBreakPointHit: TDebuggerBreakPointHitEvent; FWorkingDir: String; + FDestroyNotificationList: array [TDebuggerNotifyReason] of TMethodList; procedure DebuggerEnvironmentChanged(Sender: TObject); procedure EnvironmentChanged(Sender: TObject); function GetState: TDBGState; @@ -1534,6 +1537,8 @@ type out ADump, AStatement, AFile: String; out ALine: Integer): Boolean; deprecated; procedure LockCommandProcessing; virtual; procedure UnLockCommandProcessing; virtual; + procedure AddNotifyEvent(AReason: TDebuggerNotifyReason; AnEvent: TNotifyEvent); + procedure RemoveNotifyEvent(AReason: TDebuggerNotifyReason; AnEvent: TNotifyEvent); public property Arguments: String read FArguments write FArguments; // Arguments feed to the program property BreakPoints: TDBGBreakPoints read FBreakPoints; // list of all breakpoints @@ -1729,8 +1734,11 @@ end; constructor TDebugger.Create(const AExternalDebugger: String); var list: TStringList; + nr: TDebuggerNotifyReason; begin inherited Create; + for nr := low(TDebuggerNotifyReason) to high(TDebuggerNotifyReason) do + FDestroyNotificationList[nr] := TMethodList.Create; FOnState := nil; FOnCurrent := nil; FOnOutput := nil; @@ -1820,7 +1828,12 @@ begin end; destructor TDebugger.Destroy; +var + nr: TDebuggerNotifyReason; begin + FDestroyNotificationList[dnrDestroy].CallNotifyEvents(Self); + for nr := low(TDebuggerNotifyReason) to high(TDebuggerNotifyReason) do + FreeAndNil(FDestroyNotificationList[nr]); // don't call events FOnState := nil; FOnCurrent := nil; @@ -1868,6 +1881,16 @@ begin // nothing end; +procedure TDebugger.AddNotifyEvent(AReason: TDebuggerNotifyReason; AnEvent: TNotifyEvent); +begin + FDestroyNotificationList[AReason].Add(TMethod(AnEvent)); +end; + +procedure TDebugger.RemoveNotifyEvent(AReason: TDebuggerNotifyReason; AnEvent: TNotifyEvent); +begin + FDestroyNotificationList[AReason].Remove(TMethod(AnEvent)); +end; + procedure TDebugger.Done; begin SetState(dsNone);