mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-19 07:29:25 +02:00
IDE, Debugger: find the first stack-frame with source (e.g. if paused at exception) / avoid the asm window.
(cherry picked from commit f987f75d28
)
This commit is contained in:
parent
7663577912
commit
d76ba3ddc8
@ -123,6 +123,7 @@ type
|
||||
procedure DebuggerBeforeChangeState(ADebugger: TDebuggerIntf; AOldState: TDBGState);
|
||||
procedure DebuggerChangeState(ADebugger: TDebuggerIntf; OldState: TDBGState);
|
||||
procedure DebuggerCurrentLine(Sender: TObject; const ALocation: TDBGLocationRec);
|
||||
procedure DoDebuggerCurrentLine(Sender: TObject);
|
||||
procedure DebuggerOutput(Sender: TObject; const AText: String);
|
||||
procedure DebuggerConsoleOutput(Sender: TObject; const AText: String);
|
||||
function DebuggerFeedback(Sender: TObject; const AText, AInfo: String;
|
||||
@ -146,6 +147,7 @@ type
|
||||
FStepping, FAsmStepping: Boolean;
|
||||
// keep track of the last reported location
|
||||
FCurrentLocation: TDBGLocationRec;
|
||||
FCallStackNotification: TCallStackNotification;
|
||||
// last hit breakpoint
|
||||
FCurrentBreakpoint: TIDEBreakpoint;
|
||||
FAutoContinueTimer: TTimer;
|
||||
@ -1439,6 +1441,9 @@ begin
|
||||
if (FDebugger.State in [dsRun])
|
||||
then FCurrentBreakpoint := nil;
|
||||
|
||||
if not (FDebugger.State in [dsPause, dsInternalPause]) then
|
||||
FCallStackNotification.OnChange := nil;
|
||||
|
||||
if not((OldState = dsInternalPause) and (State = dsPause)) then begin
|
||||
// OldState=dsInternalPause means we already have a snapshot
|
||||
// Notify FSnapshots of new state (while dialogs still in updating)
|
||||
@ -1602,6 +1607,35 @@ begin
|
||||
end;
|
||||
|
||||
procedure TDebugManager.DebuggerCurrentLine(Sender: TObject; const ALocation: TDBGLocationRec);
|
||||
var
|
||||
SrcLine, TId: Integer;
|
||||
begin
|
||||
FCallStackNotification.OnChange := nil;
|
||||
if (Sender<>FDebugger) or (Sender=nil) then exit;
|
||||
if FDebugger.State = dsInternalPause then exit;
|
||||
if Destroying then exit;
|
||||
|
||||
FCurrentLocation := ALocation;
|
||||
|
||||
SrcLine := FCurrentLocation.SrcLine;
|
||||
if (SrcLine < 1) and (SrcLine <> -2) // TODO: this should move to the debugger
|
||||
// SrcLine will be -2 after stepping (gdbmi)
|
||||
then begin
|
||||
TId := Threads.CurrentThreads.CurrentThreadId;
|
||||
if CallStack.CurrentCallStackList.EntriesForThreads[TId].HasAtLeastCount(30) = nbUnknown then begin
|
||||
FCallStackNotification.OnChange := @DoDebuggerCurrentLine;
|
||||
|
||||
if FDialogs[ddtAssembler] <> nil
|
||||
then TAssemblerDlg(FDialogs[ddtAssembler]).SetLocation(FDebugger, FCurrentLocation.Address);
|
||||
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
DoDebuggerCurrentLine(nil);
|
||||
end;
|
||||
|
||||
procedure TDebugManager.DoDebuggerCurrentLine(Sender: TObject);
|
||||
// debugger paused program due to pause or error
|
||||
// -> show the current execution line in editor
|
||||
// if SrcLine < 1 then no source is available
|
||||
@ -1623,12 +1657,11 @@ var
|
||||
CurrentSourceUnitInfo: TDebuggerUnitInfo;
|
||||
a: Boolean;
|
||||
begin
|
||||
if (Sender<>FDebugger) or (Sender=nil) then exit;
|
||||
FCallStackNotification.OnChange := nil;
|
||||
if FDebugger.State = dsInternalPause then exit;
|
||||
if Destroying then exit;
|
||||
|
||||
FCurrentLocation := ALocation;
|
||||
SrcLine := ALocation.SrcLine;
|
||||
SrcLine := FCurrentLocation.SrcLine;
|
||||
CurrentSourceUnitInfo := nil;
|
||||
|
||||
if (SrcLine < 1) and (SrcLine <> -2) // TODO: this should move to the debugger
|
||||
@ -1638,12 +1671,19 @@ begin
|
||||
// TODO: Only below the frame supplied by debugger
|
||||
i:=0;
|
||||
TId := Threads.CurrentThreads.CurrentThreadId;
|
||||
if CallStack.CurrentCallStackList.EntriesForThreads[TId].HasAtLeastCount(30) = nbUnknown then begin
|
||||
FCallStackNotification.OnChange := @DoDebuggerCurrentLine;
|
||||
exit;
|
||||
end;
|
||||
|
||||
c := CallStack.CurrentCallStackList.EntriesForThreads[TId].CountLimited(30);
|
||||
while (i < c) do
|
||||
begin
|
||||
StackEntry := CallStack.CurrentCallStackList.EntriesForThreads[TId].Entries[i];
|
||||
if StackEntry.Validity = ddsRequested then // not yet available
|
||||
break;
|
||||
if StackEntry.Validity = ddsRequested then begin// not yet available
|
||||
FCallStackNotification.OnChange := @DoDebuggerCurrentLine;
|
||||
exit;
|
||||
end;
|
||||
if StackEntry.Line > 0
|
||||
then begin
|
||||
CurrentSourceUnitInfo := StackEntry.UnitInfo;
|
||||
@ -1656,14 +1696,14 @@ begin
|
||||
end;
|
||||
end
|
||||
else begin
|
||||
CurrentSourceUnitInfo := FUnitInfoProvider.GetUnitInfoFor(ALocation.SrcFile, ALocation.SrcFullName);
|
||||
CurrentSourceUnitInfo := FUnitInfoProvider.GetUnitInfoFor(FCurrentLocation.SrcFile, FCurrentLocation.SrcFullName);
|
||||
CurrentSourceUnitInfo.AddReference;
|
||||
end;
|
||||
|
||||
// TODO: do in DebuggerChangeState / Only currently State change locks execution of gdb
|
||||
// Must be after stack frame selection (for inspect)
|
||||
if FDialogs[ddtAssembler] <> nil
|
||||
then TAssemblerDlg(FDialogs[ddtAssembler]).SetLocation(FDebugger, Alocation.Address);
|
||||
then TAssemblerDlg(FDialogs[ddtAssembler]).SetLocation(FDebugger, FCurrentLocation.Address);
|
||||
|
||||
if (SrcLine > 0) and (CurrentSourceUnitInfo <> nil) and
|
||||
GetFullFilename(CurrentSourceUnitInfo, SrcFullName, True)
|
||||
@ -2047,6 +2087,10 @@ begin
|
||||
FDisassembler := TIDEDisassembler.Create;
|
||||
FRegisters := TIdeRegistersMonitor.Create;
|
||||
|
||||
FCallStackNotification := TCallStackNotification.Create;
|
||||
FCallStackNotification.AddReference;
|
||||
FCallStack.AddNotification(FCallStackNotification);
|
||||
|
||||
FSnapshots := TSnapshotManager.Create;
|
||||
FSnapshots.Threads := FThreads;
|
||||
FSnapshots.CallStack := FCallStack;
|
||||
@ -2097,6 +2141,9 @@ begin
|
||||
for DialogType := Low(TDebugDialogType) to High(TDebugDialogType) do
|
||||
DestroyDebugDialog(DialogType);
|
||||
|
||||
if FCallStackNotification <> nil then
|
||||
FCallStackNotification.ReleaseReference;
|
||||
|
||||
SetDebugger(nil);
|
||||
|
||||
FreeAndNil(FCurrentWatches);
|
||||
|
Loading…
Reference in New Issue
Block a user