mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-18 02:59:17 +02:00
FpDebug: Fix SEH-finally block detection on Win
This commit is contained in:
parent
dfce0d15a4
commit
c0907fabd1
@ -1111,6 +1111,7 @@ DECL = DW_AT_decl_column, DW_AT_decl_file, DW_AT_decl_line
|
|||||||
|
|
||||||
property DbgInfo: TFpDwarfInfo read FDwarf;
|
property DbgInfo: TFpDwarfInfo read FDwarf;
|
||||||
property ProcAddress: TDBGPtr read FAddress;
|
property ProcAddress: TDBGPtr read FAddress;
|
||||||
|
property AddressInfo: PDwarfAddressInfo read FAddressInfo;
|
||||||
public
|
public
|
||||||
constructor Create(ACompilationUnit: TDwarfCompilationUnit; AInfo: PDwarfAddressInfo; AAddress: TDbgPtr; ADbgInfo: TFpDwarfInfo = nil); overload;
|
constructor Create(ACompilationUnit: TDwarfCompilationUnit; AInfo: PDwarfAddressInfo; AAddress: TDbgPtr; ADbgInfo: TFpDwarfInfo = nil); overload;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
|
@ -2505,9 +2505,11 @@ function TFpSymbolDwarfFreePascalDataProc.ResolveInternalFinallySymbol(
|
|||||||
{$IfDef WINDOWS}
|
{$IfDef WINDOWS}
|
||||||
var
|
var
|
||||||
StartPC, EndPC: TDBGPtr;
|
StartPC, EndPC: TDBGPtr;
|
||||||
HelpSymbol, HelpSymbol2: TFpSymbolDwarf;
|
HelpSymbol2: TFpSymbolDwarf;
|
||||||
AnAddresses: TDBGPtrArray;
|
AnAddresses: TDBGPtrArray;
|
||||||
FndLine, i: Integer;
|
FndLine, i: Integer;
|
||||||
|
SM1: TDwarfLineInfoStateMachine;
|
||||||
|
ThePrologueLineNum, TheStartLine: Cardinal;
|
||||||
{$EndIf}
|
{$EndIf}
|
||||||
begin
|
begin
|
||||||
Result := Self;
|
Result := Self;
|
||||||
@ -2517,37 +2519,44 @@ begin
|
|||||||
// On Windows: If in an SEH finally block, try to get the real procedure
|
// On Windows: If in an SEH finally block, try to get the real procedure
|
||||||
// Look for the line, before the finally statement.
|
// Look for the line, before the finally statement.
|
||||||
// TODO: This needs to move to a win-specific class, and ideally a FPC specific class too.
|
// TODO: This needs to move to a win-specific class, and ideally a FPC specific class too.
|
||||||
if ('$fin' = copy(Name,1, 4) ) and
|
debugln(['=========== !!!!!!!! ',Name ]);
|
||||||
|
if ( ('$fin' = copy(Name,1, 4)) or ('fin$' = copy(Name,1, 4)) ) and
|
||||||
CompilationUnit.GetProcStartEnd(ProcAddress, StartPC, EndPC) and
|
CompilationUnit.GetProcStartEnd(ProcAddress, StartPC, EndPC) and
|
||||||
(StartPC <> 0)
|
(StartPC <> 0)
|
||||||
then begin
|
then begin
|
||||||
// TODO: use the assembler to skip the prologue
|
(* The first line is the prologue and usually FPC stores the "end" line number.
|
||||||
StartPC := StartPC + 9; // fpc puts the first 9 bytes on "end"
|
Get the 2nd line number in the finally-proc and see if it is before the prologue *)
|
||||||
|
TheStartLine := 0;
|
||||||
|
SM1 := AddressInfo^.StateMachine.Clone;
|
||||||
|
ThePrologueLineNum := SM1.Line;
|
||||||
|
debugln(['=========== !!!!!!!! PL ', ThePrologueLineNum]);
|
||||||
|
SM1.NextLine;
|
||||||
|
if not SM1.EndSequence then begin
|
||||||
|
TheStartLine := SM1.Line;
|
||||||
|
debugln(['=========== !!!!!!!! SL ', TheStartLine]);
|
||||||
|
if (TheStartLine=0) or (TheStartLine=ThePrologueLineNum) then begin
|
||||||
|
SM1.NextLine;
|
||||||
|
if not SM1.EndSequence then
|
||||||
|
TheStartLine := SM1.Line;
|
||||||
|
debugln(['=========== !!!!!!!! SL ', TheStartLine]);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
if (TheStartLine > ThePrologueLineNum) or (TheStartLine = 0) then
|
||||||
|
TheStartLine := ThePrologueLineNum;
|
||||||
|
SM1.Free;
|
||||||
|
debugln(['=========== !!!!!!!! SL <<<< ', TheStartLine]);
|
||||||
|
|
||||||
|
|
||||||
if EndPC < StartPC then
|
if EndPC < StartPC then
|
||||||
EndPC := StartPC;
|
EndPC := StartPC;
|
||||||
|
|
||||||
if StartPC = ProcAddress then begin
|
|
||||||
TFpSymbol(HelpSymbol) := Self;
|
|
||||||
HelpSymbol.AddReference;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
TFpSymbol(HelpSymbol) := DbgInfo.FindProcSymbol(StartPC); // same proc as self, but will return the FIRTS line
|
|
||||||
|
|
||||||
if (HelpSymbol = nil) or (HelpSymbol.CompilationUnit <> CompilationUnit) or
|
|
||||||
(not HelpSymbol.InheritsFrom(TFpSymbolDwarfFreePascalDataProc))
|
|
||||||
then begin
|
|
||||||
HelpSymbol.ReleaseReference;
|
|
||||||
exit
|
|
||||||
end;
|
|
||||||
|
|
||||||
AnAddresses := nil;
|
AnAddresses := nil;
|
||||||
if
|
if CompilationUnit.Owner.GetLineAddresses(FileName, TheStartLine, AnAddresses, fsBefore, @FndLine) and
|
||||||
//(FndLine = HelpSymbol.Line) and
|
|
||||||
HelpSymbol.CompilationUnit.Owner.GetLineAddresses(HelpSymbol.FileName, HelpSymbol.Line, AnAddresses, fsBefore, @FndLine) and
|
|
||||||
(Length(AnAddresses) > 1) // may be an internal finally on the begin/end line, sharing a line number
|
(Length(AnAddresses) > 1) // may be an internal finally on the begin/end line, sharing a line number
|
||||||
then begin
|
then begin
|
||||||
|
debugln(['=========== !!!!!!!! AAAA ', Length(AnAddresses) ]);
|
||||||
for i := 0 to Length(AnAddresses) - 1 do
|
for i := 0 to Length(AnAddresses) - 1 do
|
||||||
if (AnAddresses[i] < StartPC - 9) or (AnAddresses[i] > EndPC) then begin
|
if (AnAddresses[i] < StartPC) or (AnAddresses[i] > EndPC) then begin
|
||||||
TFpSymbol(HelpSymbol2) := DbgInfo.FindProcSymbol(AnAddresses[i]);
|
TFpSymbol(HelpSymbol2) := DbgInfo.FindProcSymbol(AnAddresses[i]);
|
||||||
if (HelpSymbol2 <> nil) and (HelpSymbol2.CompilationUnit = CompilationUnit) and
|
if (HelpSymbol2 <> nil) and (HelpSymbol2.CompilationUnit = CompilationUnit) and
|
||||||
(HelpSymbol2.InheritsFrom(TFpSymbolDwarfFreePascalDataProc)) and
|
(HelpSymbol2.InheritsFrom(TFpSymbolDwarfFreePascalDataProc)) and
|
||||||
@ -2556,7 +2565,6 @@ begin
|
|||||||
Result := HelpSymbol2;
|
Result := HelpSymbol2;
|
||||||
// *** FOrigSymbol has now the reference that the caller had. ***
|
// *** FOrigSymbol has now the reference that the caller had. ***
|
||||||
TFpSymbolDwarfFreePascalDataProc(Result).FOrigSymbol := Self;
|
TFpSymbolDwarfFreePascalDataProc(Result).FOrigSymbol := Self;
|
||||||
HelpSymbol.ReleaseReference;
|
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
HelpSymbol2.ReleaseReference;
|
HelpSymbol2.ReleaseReference;
|
||||||
@ -2564,8 +2572,10 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
AnAddresses := nil;
|
AnAddresses := nil;
|
||||||
if HelpSymbol.CompilationUnit.Owner.GetLineAddresses(HelpSymbol.FileName, HelpSymbol.Line-1, AnAddresses, fsBefore)
|
if CompilationUnit.Owner.GetLineAddresses(FileName, TheStartLine-1, AnAddresses, fsBefore)
|
||||||
then begin
|
then begin
|
||||||
|
debugln(['=========== !!!!!!!! BBB', Length(AnAddresses) ]);
|
||||||
|
|
||||||
TFpSymbol(HelpSymbol2) := DbgInfo.FindProcSymbol(AnAddresses[0]);
|
TFpSymbol(HelpSymbol2) := DbgInfo.FindProcSymbol(AnAddresses[0]);
|
||||||
if (HelpSymbol2 <> nil) and (HelpSymbol2.CompilationUnit = CompilationUnit) and
|
if (HelpSymbol2 <> nil) and (HelpSymbol2.CompilationUnit = CompilationUnit) and
|
||||||
(HelpSymbol2.InheritsFrom(TFpSymbolDwarfFreePascalDataProc))
|
(HelpSymbol2.InheritsFrom(TFpSymbolDwarfFreePascalDataProc))
|
||||||
@ -2573,12 +2583,10 @@ begin
|
|||||||
Result := HelpSymbol2;
|
Result := HelpSymbol2;
|
||||||
// *** FOrigSymbol has now the reference that the caller had. ***
|
// *** FOrigSymbol has now the reference that the caller had. ***
|
||||||
TFpSymbolDwarfFreePascalDataProc(Result).FOrigSymbol := Self;
|
TFpSymbolDwarfFreePascalDataProc(Result).FOrigSymbol := Self;
|
||||||
HelpSymbol.ReleaseReference;
|
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
HelpSymbol2.ReleaseReference;
|
HelpSymbol2.ReleaseReference;
|
||||||
end;
|
end;
|
||||||
HelpSymbol.ReleaseReference;
|
|
||||||
end;
|
end;
|
||||||
{$EndIf}
|
{$EndIf}
|
||||||
end;
|
end;
|
||||||
|
@ -518,6 +518,10 @@ begin
|
|||||||
Debugger.SetBreakPoint(Src, 'WatchesScopeUnit2.pas', 'MethodMainBaseBase');
|
Debugger.SetBreakPoint(Src, 'WatchesScopeUnit2.pas', 'MethodMainBaseBase');
|
||||||
|
|
||||||
Debugger.SetBreakPoint(Src, 'Prg');
|
Debugger.SetBreakPoint(Src, 'Prg');
|
||||||
|
|
||||||
|
Debugger.SetBreakPoint(Src, 'FuncFin1');
|
||||||
|
Debugger.SetBreakPoint(Src, 'FuncFin2');
|
||||||
|
Debugger.SetBreakPoint(Src, 'FuncFin3');
|
||||||
AssertDebuggerNotInErrorState;
|
AssertDebuggerNotInErrorState;
|
||||||
|
|
||||||
(* ************ Nested Functions ************* *)
|
(* ************ Nested Functions ************* *)
|
||||||
@ -604,6 +608,37 @@ begin
|
|||||||
t.EvaluateWatches;
|
t.EvaluateWatches;
|
||||||
t.CheckResults;
|
t.CheckResults;
|
||||||
|
|
||||||
|
|
||||||
|
(* ************ finally ************* *)
|
||||||
|
|
||||||
|
Debugger.RunToNextPause(dcRun);
|
||||||
|
AssertDebuggerState(dsPause);
|
||||||
|
t.Clear;
|
||||||
|
t.Add('FinFoo1', 'FinFoo1' , 123);
|
||||||
|
t.Add('FinFoo2', 'FinFoo2' , 456);
|
||||||
|
t.Add('FinFoo3', 'FinFoo3' , 789);
|
||||||
|
t.EvaluateWatches;
|
||||||
|
t.CheckResults;
|
||||||
|
|
||||||
|
Debugger.RunToNextPause(dcRun);
|
||||||
|
AssertDebuggerState(dsPause);
|
||||||
|
t.Clear;
|
||||||
|
t.Add('FinFoo1', 'FinFoo1' , 123);
|
||||||
|
t.Add('FinFoo2', 'FinFoo2' , 456);
|
||||||
|
t.Add('FinFoo3', 'FinFoo3' , 789);
|
||||||
|
t.EvaluateWatches;
|
||||||
|
t.CheckResults;
|
||||||
|
|
||||||
|
Debugger.RunToNextPause(dcRun);
|
||||||
|
AssertDebuggerState(dsPause);
|
||||||
|
t.Clear;
|
||||||
|
t.Add('FinFoo1', 'FinFoo1' , 123);
|
||||||
|
t.Add('FinFoo2', 'FinFoo2' , 456);
|
||||||
|
t.Add('FinFoo3', 'FinFoo3' , 789);
|
||||||
|
t.EvaluateWatches;
|
||||||
|
t.CheckResults;
|
||||||
|
|
||||||
|
|
||||||
finally
|
finally
|
||||||
Debugger.RunToNextPause(dcStop);
|
Debugger.RunToNextPause(dcStop);
|
||||||
t.Free;
|
t.Free;
|
||||||
|
Binary file not shown.
@ -243,7 +243,23 @@ begin
|
|||||||
BreakDummy := 1; // TEST_BREAKPOINT=FuncFoo
|
BreakDummy := 1; // TEST_BREAKPOINT=FuncFoo
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TestFin;
|
||||||
|
var
|
||||||
|
FinFoo1, FinFoo2, FinFoo3: integer;
|
||||||
|
a: Integer;
|
||||||
|
begin
|
||||||
|
try
|
||||||
|
FinFoo1 := 123;
|
||||||
|
FinFoo2 := 456;
|
||||||
|
FinFoo3 := 789;
|
||||||
|
finally
|
||||||
|
a := FinFoo1; // TEST_BREAKPOINT=FuncFin1
|
||||||
|
a := a + FinFoo2 + 1;
|
||||||
|
a := a + FinFoo3 + 2; // TEST_BREAKPOINT=FuncFin2
|
||||||
|
a := a + FinFoo1;
|
||||||
|
FinFoo1 := a; // TEST_BREAKPOINT=FuncFin3
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Unit1Init;
|
Unit1Init;
|
||||||
@ -266,4 +282,6 @@ begin
|
|||||||
TestClassMainChild.MethodMainBaseBase();
|
TestClassMainChild.MethodMainBaseBase();
|
||||||
|
|
||||||
BreakDummy := 1; // TEST_BREAKPOINT=Prg
|
BreakDummy := 1; // TEST_BREAKPOINT=Prg
|
||||||
|
|
||||||
|
TestFin;
|
||||||
end.
|
end.
|
||||||
|
Loading…
Reference in New Issue
Block a user