mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-17 11:09:09 +02:00
LazDebuggerGdbmi: Tests for Step to finally/except for Win64 SEH
git-svn-id: trunk@62315 -
This commit is contained in:
parent
5cb2cd173d
commit
cdad0cd83f
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -2583,6 +2583,7 @@ components/lazdebuggergdbmi/test/TestApps/EnvPrg.pas svneol=native#text/pascal
|
||||
components/lazdebuggergdbmi/test/TestApps/ExceptPrg.pas svneol=native#text/pascal
|
||||
components/lazdebuggergdbmi/test/TestApps/ExceptPrgStep.pas svneol=native#text/pascal
|
||||
components/lazdebuggergdbmi/test/TestApps/ExceptPrgStepOver.pas svneol=native#text/pascal
|
||||
components/lazdebuggergdbmi/test/TestApps/ExceptTestPrg.pas svneol=native#text/pascal
|
||||
components/lazdebuggergdbmi/test/TestApps/WatchesPrg.pas svneol=native#text/pascal
|
||||
components/lazdebuggergdbmi/test/TestApps/WatchesPrgArray.inc svneol=native#text/pascal
|
||||
components/lazdebuggergdbmi/test/TestApps/WatchesPrgEnum.inc svneol=native#text/pascal
|
||||
|
@ -17,7 +17,7 @@ begin
|
||||
foo;
|
||||
foo;
|
||||
except
|
||||
Freemem(GetMem(1));
|
||||
Freemem(GetMem(1)); // TEST_BREAKPOINT=BREAK_LINE_EXCEPT_1
|
||||
end;
|
||||
Freemem(GetMem(2));
|
||||
|
||||
@ -28,11 +28,11 @@ begin
|
||||
foo;
|
||||
foo;
|
||||
except
|
||||
Freemem(GetMem(1));
|
||||
Freemem(GetMem(1)); // TEST_BREAKPOINT=BREAK_LINE_EXCEPT_2
|
||||
end;
|
||||
Freemem(GetMem(2));
|
||||
except
|
||||
Freemem(GetMem(1));
|
||||
Freemem(GetMem(1)); // TEST_BREAKPOINT=BREAK_LINE_EXCEPT_3
|
||||
end;
|
||||
|
||||
try
|
||||
@ -47,11 +47,11 @@ begin
|
||||
raise Exception.create('xxx');
|
||||
Freemem(GetMem(2));
|
||||
except
|
||||
Freemem(GetMem(1));
|
||||
Freemem(GetMem(1)); // TEST_BREAKPOINT=BREAK_LINE_EXCEPT_4
|
||||
end;
|
||||
|
||||
Freemem(GetMem(2));
|
||||
Freemem(GetMem(2));
|
||||
Freemem(GetMem(2)); // TEST_BREAKPOINT=BREAK_LINE_EXCEPT_END
|
||||
Freemem(GetMem(2));
|
||||
|
||||
end.
|
||||
|
206
components/lazdebuggergdbmi/test/TestApps/ExceptTestPrg.pas
Normal file
206
components/lazdebuggergdbmi/test/TestApps/ExceptTestPrg.pas
Normal file
@ -0,0 +1,206 @@
|
||||
program ExceptTestPrg;
|
||||
uses sysutils;
|
||||
|
||||
{off $DEFINE With_Implicit_Finally}
|
||||
|
||||
type
|
||||
MyExceptionIgnore = class(Exception) end;
|
||||
|
||||
var
|
||||
TestVal: integer;
|
||||
ControlRecurseStep3Outer, ControlRecurseRaise: Integer;
|
||||
|
||||
procedure Nop;
|
||||
begin
|
||||
Freemem(GetMem(1));
|
||||
end;
|
||||
|
||||
procedure MyRaise;
|
||||
begin
|
||||
if ControlRecurseRaise >= 0 then begin
|
||||
ControlRecurseRaise := 0;
|
||||
raise Exception.create('a'); // TEST_BREAKPOINT=BrkMyRaise
|
||||
end;
|
||||
|
||||
Freemem(GetMem(1));
|
||||
end;
|
||||
|
||||
procedure Step3Finally; forward;
|
||||
procedure Step3FinallyOuter; forward;
|
||||
|
||||
|
||||
procedure Step3FinallyOuterRecurse;
|
||||
begin
|
||||
ControlRecurseStep3Outer := 0; // only one recursion
|
||||
if ControlRecurseRaise > 0 then ControlRecurseRaise := -1;
|
||||
Step3FinallyOuter;
|
||||
end;
|
||||
|
||||
procedure Step3Finally;
|
||||
{$IFDEF With_Implicit_Finally}
|
||||
var
|
||||
a: Ansistring; // currently stepping into implicit finally handlers
|
||||
{$ENDIF}
|
||||
begin
|
||||
try
|
||||
try
|
||||
Nop;
|
||||
try
|
||||
Nop;
|
||||
{$IFDEF With_Implicit_Finally}
|
||||
a := 'a';
|
||||
{$ENDIF}
|
||||
MyRaise;
|
||||
Nop; // TEST_BREAKPOINT=BrkDeadCode3Fin
|
||||
|
||||
|
||||
finally
|
||||
Nop; // TEST_BREAKPOINT=BrkStep3Fin_A
|
||||
{$IFDEF With_Implicit_Finally}
|
||||
a := a + 'b';
|
||||
{$ENDIF}
|
||||
TestVal := TestVal + 1;
|
||||
if ControlRecurseStep3Outer = 1 then
|
||||
Step3FinallyOuterRecurse;
|
||||
nop; end; // TEST_BREAKPOINT=BrkStep3Fin_A_END
|
||||
|
||||
|
||||
finally
|
||||
Nop; // TEST_BREAKPOINT=BrkStep3Fin_B
|
||||
TestVal := TestVal + 1;
|
||||
//if ControlRecurseStep3Outer = XXX then
|
||||
// Step3FinallyOuterRecurse;
|
||||
nop; end; // TEST_BREAKPOINT=BrkStep3Fin_B_END
|
||||
|
||||
|
||||
finally
|
||||
Nop; // TEST_BREAKPOINT=BrkStep3Fin_C
|
||||
TestVal := TestVal + 1;
|
||||
if ControlRecurseStep3Outer = 2 then
|
||||
Step3FinallyOuterRecurse;
|
||||
nop; end; // TEST_BREAKPOINT=BrkStep3Fin_C_END
|
||||
|
||||
|
||||
Nop;
|
||||
end;
|
||||
|
||||
procedure Step3FinallyOuter;
|
||||
{$IFDEF With_Implicit_Finally}
|
||||
var
|
||||
a: Ansistring;
|
||||
{$ENDIF}
|
||||
begin
|
||||
try
|
||||
try
|
||||
Nop;
|
||||
try
|
||||
Nop;
|
||||
{$IFDEF With_Implicit_Finally}
|
||||
a := 'a';
|
||||
{$ENDIF}
|
||||
Step3Finally;
|
||||
Nop; // TEST_BREAKPOINT=BrkDeadCode3FinOuter
|
||||
|
||||
|
||||
finally
|
||||
Nop; // TEST_BREAKPOINT=BrkStep3FinOuter_A
|
||||
{$IFDEF With_Implicit_Finally}
|
||||
a := a + 'b';
|
||||
{$ENDIF}
|
||||
TestVal := TestVal + 1;
|
||||
if ControlRecurseStep3Outer = 3 then
|
||||
Step3FinallyOuterRecurse;
|
||||
nop; end; // TEST_BREAKPOINT=BrkStep3FinOuter_A_END
|
||||
|
||||
|
||||
finally
|
||||
Nop; // TEST_BREAKPOINT=BrkStep3FinOuter_B
|
||||
TestVal := TestVal + 1;
|
||||
//if ControlRecurseStep3Outer = XXX then
|
||||
// Step3FinallyOuterRecurse;
|
||||
nop; end; // TEST_BREAKPOINT=BrkStep3FinOuter_B_END
|
||||
|
||||
|
||||
finally
|
||||
Nop; // TEST_BREAKPOINT=BrkStep3FinOuter_C
|
||||
TestVal := TestVal + 1;
|
||||
if ControlRecurseStep3Outer = 4 then
|
||||
Step3FinallyOuterRecurse;
|
||||
nop; end; // TEST_BREAKPOINT=BrkStep3FinOuter_C_END
|
||||
|
||||
|
||||
Nop;
|
||||
end;
|
||||
|
||||
procedure NestedExcept(a: integer = 0);
|
||||
begin
|
||||
try
|
||||
try
|
||||
MyRaise;
|
||||
nop; // TEST_BREAKPOINT=BrkStepNestedExcept_DEAD
|
||||
|
||||
finally
|
||||
nop; // TEST_BREAKPOINT=BrkStepNestedExcept_Finally
|
||||
nop;
|
||||
if a = 0 then
|
||||
NestedExcept(1); // TEST_BREAKPOINT=BrkStepNestedExcept_Finally_BEFORE
|
||||
nop; // TEST_BREAKPOINT=BrkStepNestedExcept_Finally_AFTER
|
||||
nop;
|
||||
nop; end; // TEST_BREAKPOINT=BrkStepNestedExcept_Finally_END
|
||||
|
||||
nop; except // some fpc versions put debug line for except, at the end of previous statement
|
||||
nop; // TEST_BREAKPOINT=BrkStepNestedExcept
|
||||
nop;
|
||||
nop; end; // TEST_BREAKPOINT=BrkStepNestedExcept_END
|
||||
|
||||
end;
|
||||
|
||||
var
|
||||
RecStep, RecRaise: Integer;
|
||||
begin
|
||||
for RecRaise := 0 to 2 do // ignore or break at recurse
|
||||
for RecStep := 0 to 4 do
|
||||
if (RecRaise = 0) or (RecStep in [0,1,4]) then
|
||||
begin
|
||||
try
|
||||
ControlRecurseStep3Outer := RecStep;
|
||||
ControlRecurseRaise := 0;
|
||||
if RecRaise = 2 then
|
||||
ControlRecurseRaise := 1; // do not raise in recurse, but enter all the finally without stopping
|
||||
TestVal := 1;
|
||||
Step3FinallyOuter;
|
||||
nop; // TEST_BREAKPOINT=BrkMainDeadCode1
|
||||
|
||||
|
||||
nop; except // some fpc versions put debug line for except, at the end of previous statement
|
||||
nop; // TEST_BREAKPOINT=BrkStepMainExcept1
|
||||
nop;
|
||||
TestVal := TestVal + 1;
|
||||
end;
|
||||
|
||||
|
||||
Nop; // TEST_BREAKPOINT=BrkStepMainAfterExcept1
|
||||
end;
|
||||
|
||||
ControlRecurseRaise := 0;
|
||||
NestedExcept;
|
||||
Nop;
|
||||
|
||||
ControlRecurseRaise := 0;
|
||||
NestedExcept;
|
||||
Nop;
|
||||
|
||||
|
||||
// Do NOT step to finally, but set a breakpoint in it. Then step to next finally
|
||||
nop;
|
||||
nop; // TEST_BREAKPOINT=BrkMain1
|
||||
ControlRecurseStep3Outer := 0;
|
||||
ControlRecurseRaise := 0;
|
||||
TestVal := 1;
|
||||
try
|
||||
Step3FinallyOuter;
|
||||
except
|
||||
end;
|
||||
|
||||
|
||||
end.
|
@ -308,6 +308,7 @@ end;
|
||||
function TGDBTestCase.StartGDB(AppDir, TestExeName: String): TGDBMIDebugger;
|
||||
begin
|
||||
Result := GdbClass.Create(DebuggerInfo.ExeName);
|
||||
Debugger.LazDebugger := Result;
|
||||
Result.OnDbgOutput := @InternalDbgOutPut;
|
||||
Result.OnFeedback := @InternalFeedBack;
|
||||
Result.OnDbgEvent:=@InternalDbgEvent;
|
||||
@ -432,6 +433,7 @@ initialization
|
||||
DebugLogger.FindOrRegisterLogGroup('DBG_DISASSEMBLER', True )^.Enabled := True;
|
||||
DebugLogger.FindOrRegisterLogGroup('DBGMI_TYPE_INFO', True )^.Enabled := True;
|
||||
DebugLogger.FindOrRegisterLogGroup('DBGMI_TIMEOUT_DEBUG', True )^.Enabled := True;
|
||||
DebugLogger.FindOrRegisterLogGroup('DBG_THREAD_AND_FRAME', True )^.Enabled := True;
|
||||
|
||||
DebugLogger.FindOrRegisterLogGroup('FPDBG_DWARF_ERRORS', True);
|
||||
DebugLogger.FindOrRegisterLogGroup('FPDBG_DWARF_SEARCH', True)^.Enabled := True;
|
||||
|
@ -7,7 +7,7 @@ interface
|
||||
uses
|
||||
Classes, sysutils, fpcunit, testutils, testregistry, TestBase, GDBMIDebugger,
|
||||
LCLProc, DbgIntfDebuggerBase, TestDbgControl, TestDbgTestSuites,
|
||||
TestDbgConfig;
|
||||
TestDbgConfig, TestCommonSources, TestOutputLogger;
|
||||
|
||||
type
|
||||
|
||||
@ -15,6 +15,8 @@ type
|
||||
|
||||
TTestExceptionOne = class(TGDBTestCase)
|
||||
private
|
||||
Src: TCommonSource;
|
||||
|
||||
FCurLine: Integer;
|
||||
FCurFile: string;
|
||||
|
||||
@ -36,10 +38,16 @@ type
|
||||
|
||||
function GetLogFileName: String; override;
|
||||
procedure DoCurrent(Sender: TObject; const ALocation: TDBGLocationRec);
|
||||
procedure TestLocation(ATestName, ABrkName: String; AnAllowLineBefore: Integer = 0; AnAltBrkName: String = '');
|
||||
function IsAtLine(ABrkName: String; ATrueOnNoLine: Boolean = False): Boolean;
|
||||
function StepOverToLine(ATestName, ABrkName: String; AnExitIfNoLineInfo: Boolean = False): Boolean;
|
||||
function StepOverLeaveFinally(ATestName: String): Boolean;
|
||||
published
|
||||
procedure TestException;
|
||||
procedure TestExceptionStepOut;
|
||||
procedure TestExceptionStepOver;
|
||||
procedure TestExceptionStepOutEx; // Extended for SEH
|
||||
procedure TestExceptionStepOverEx; // Extended for SEH
|
||||
end;
|
||||
|
||||
{ TTestExceptionAddrDirect }
|
||||
@ -86,7 +94,9 @@ const
|
||||
|
||||
implementation
|
||||
var
|
||||
ControlTestExceptionOne, ControlTestExceptionOneException, ControlTestExceptionOneExceptionStepOut, ControlTestExceptionOneExceptionStepOver: Pointer;
|
||||
ControlTestExceptionOne, ControlTestExceptionOneException,
|
||||
ControlTestExceptionOneExceptionStepOut, ControlTestExceptionOneExceptionStepOver,
|
||||
ControlTestExceptionOneExceptionStepOutEx, ControlTestExceptionOneExceptionStepOverEx: Pointer;
|
||||
|
||||
{ TTestExceptionForceName }
|
||||
|
||||
@ -431,7 +441,9 @@ begin
|
||||
ClearTestErrors;
|
||||
FContinue := False;
|
||||
|
||||
TestCompile(AppDir + 'ExceptPrgStep.pas', TestExeName, '', '');
|
||||
Src := GetCommonSourceFor(AppDir + 'ExceptPrgStep.pas');
|
||||
TestCompile(Src, TestExeName);
|
||||
|
||||
FGotExceptCount := 0; TstName := 'STEP';
|
||||
dbg := StartGDB(AppDir, TestExeName);
|
||||
try
|
||||
@ -505,7 +517,9 @@ begin
|
||||
ClearTestErrors;
|
||||
FContinue := True;
|
||||
|
||||
TestCompile(AppDir + 'ExceptPrgStepOver.pas', TestExeName, '', '');
|
||||
Src := GetCommonSourceFor(AppDir + 'ExceptPrgStepOver.pas');
|
||||
TestCompile(Src, TestExeName, '', '');
|
||||
|
||||
FGotExceptCount := 0; TstName := 'STEPOVER ';
|
||||
dbg := StartGDB(AppDir, TestExeName);
|
||||
try
|
||||
@ -583,6 +597,402 @@ begin
|
||||
AssertTestErrors;
|
||||
end;
|
||||
|
||||
|
||||
procedure TTestExceptionOne.TestLocation(ATestName, ABrkName: String;
|
||||
AnAllowLineBefore: Integer; AnAltBrkName: String);
|
||||
var
|
||||
l, b: Integer;
|
||||
ok: Boolean;
|
||||
lc: TDBGLocationRec;
|
||||
begin
|
||||
AssertDebuggerState(dsPause, ATestName);
|
||||
lc := Debugger.LazDebugger.GetLocation;
|
||||
l := lc.SrcLine;
|
||||
b := Src.BreakPoints[ABrkName];
|
||||
ATestName := ATestName + ' Loc at Line=' + IntToStr(l) + ' ' + lc.SrcFile + ' Expected='+IntToStr(b)+' '+ABrkName;
|
||||
ok := (l >= b - AnAllowLineBefore) and (l <= b);
|
||||
if (AnAltBrkName = '') or ok then begin
|
||||
TestTrue(ATestName+' '+ABrkName+' Loc', ok);
|
||||
end
|
||||
else begin
|
||||
ATestName := ATestName + ' ALTERNATE-Exp='+IntToStr(b)+ ' '+AnAltBrkName;
|
||||
b := Src.BreakPoints[AnAltBrkName];
|
||||
if b=l then
|
||||
TestTrue(ATestName+' '+ABrkName+' Loc', false, 0, ' // Ignored for alternate name');
|
||||
TestTrue(ATestName+' '+ABrkName+' Loc', b = l);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TTestExceptionOne.IsAtLine(ABrkName: String; ATrueOnNoLine: Boolean
|
||||
): Boolean;
|
||||
var
|
||||
l, b: Integer;
|
||||
lc: TDBGLocationRec;
|
||||
begin
|
||||
lc := Debugger.LazDebugger.GetLocation;
|
||||
if (lc.SrcFile = '') then
|
||||
exit(ATrueOnNoLine);
|
||||
|
||||
l := Debugger.LazDebugger.GetLocation.SrcLine;
|
||||
b := Src.BreakPoints[ABrkName];
|
||||
Result := b = l;
|
||||
end;
|
||||
|
||||
function TTestExceptionOne.StepOverToLine(ATestName, ABrkName: String;
|
||||
AnExitIfNoLineInfo: Boolean): Boolean;
|
||||
var
|
||||
mx: Integer;
|
||||
begin
|
||||
mx := 100; // max steps
|
||||
Result := True;
|
||||
while not IsAtLine(ABrkName, AnExitIfNoLineInfo) do begin
|
||||
Debugger.LazDebugger.StepOver;
|
||||
AssertDebuggerState(dsPause, ATestName);
|
||||
dec(mx);
|
||||
if mx = 0 then begin
|
||||
TestTrue(ATestName+'reached step target '+ ABrkName, False);
|
||||
Result := False;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
debugln(['XXXXXXXXXXXXXXXXXXXXXXXX to ', ABrkName, ' ',ATestName]);
|
||||
end;
|
||||
|
||||
function TTestExceptionOne.StepOverLeaveFinally(ATestName: String): Boolean;
|
||||
var
|
||||
mx: Integer;
|
||||
lc1, lc2: TDBGLocationRec;
|
||||
begin
|
||||
Result := True;
|
||||
//somehow gdb does not always a full step, but does asm stepping on the "end" line
|
||||
lc1 := Debugger.LazDebugger.GetLocation;
|
||||
Debugger.LazDebugger.StepOver;
|
||||
AssertDebuggerState(dsPause, ATestName);
|
||||
|
||||
// some lines in the "end" keyword may be without line number (for gdb), and not step correctly
|
||||
lc2 := Debugger.LazDebugger.GetLocation;
|
||||
if (lc2.SrcLine > 0) or (lc1.FuncName <> lc2.FuncName) then
|
||||
exit;
|
||||
|
||||
if lc1.FuncName = lc2.FuncName then TestTrue('BAD FIN STEP ' + ATestName, false, 0, ' ignore');
|
||||
|
||||
mx := 5; // max steps
|
||||
while (lc1.FuncName = lc2.FuncName) and (lc2.SrcLine < 1) do begin
|
||||
Debugger.LazDebugger.StepOver;
|
||||
AssertDebuggerState(dsPause, ATestName);
|
||||
dec(mx);
|
||||
if mx = 0 then begin
|
||||
TestTrue(ATestName+'reached step target FIN', False);
|
||||
Result := False;
|
||||
break;
|
||||
end;
|
||||
lc2 := Debugger.LazDebugger.GetLocation;
|
||||
end;
|
||||
debugln(['XXXXXXXXXXXXXXXXXXXXXXXX to FIN ',ATestName]);
|
||||
end;
|
||||
|
||||
procedure TTestExceptionOne.TestExceptionStepOutEx;
|
||||
function StepIfAtLine(ATestName, ABrkName: String): Boolean;
|
||||
begin
|
||||
Result := True;
|
||||
if not IsAtLine(ABrkName) then
|
||||
exit;
|
||||
Debugger.LazDebugger.StepOver;
|
||||
TestTrue(ATestName+' finally entered at begin (not end) / '+ ABrkName, False, 0, 'ignore');
|
||||
AssertDebuggerState(dsPause, ATestName);
|
||||
debugln(['XXXXXXXXXXXXXXXXXXXXXXXX STEPPED from END LINE to begin??? ', ABrkName, ' ',ATestName]);
|
||||
end;
|
||||
|
||||
var
|
||||
ExeName, TstName: String;
|
||||
dbg: TGDBMIDebugger;
|
||||
begin
|
||||
if SkipTest then exit;
|
||||
if not TestControlCanTest(ControlTestExceptionOneExceptionStepOutEx) then exit;
|
||||
ClearTestErrors;
|
||||
|
||||
Src := GetCommonSourceFor(AppDir + 'ExceptTestPrg.pas');
|
||||
TestCompile(Src, ExeName);
|
||||
|
||||
dbg := StartGDB(AppDir, ExeName);
|
||||
try
|
||||
dbg.Exceptions.Add('MyExceptionIgnore').Enabled := False;
|
||||
dbg.OnException := @DoDebuggerException;
|
||||
dbg.OnCurrent := @DoCurrent;
|
||||
|
||||
TstName := ' Run to Except';
|
||||
FContinue := False;
|
||||
dbg.Run;
|
||||
TestEquals(TstName+': Got 1 exceptions: ', 1, FGotExceptCount);
|
||||
TestLocation(TstName+': CurLine ', 'BrkMyRaise');
|
||||
FContinue := True;
|
||||
|
||||
dbg.StepOver;
|
||||
StepIfAtLine(TstName, 'BrkStep3Fin_A_END');
|
||||
TestLocation(TstName+': CurLine ', 'BrkStep3Fin_A', 1);
|
||||
|
||||
dbg.StepOut;
|
||||
StepIfAtLine(TstName, 'BrkStep3FinOuter_A_END');
|
||||
TestLocation(TstName+': CurLine ', 'BrkStep3FinOuter_A', 1);
|
||||
|
||||
dbg.StepOut;
|
||||
TestLocation(TstName+': CurLine ', 'BrkStepMainExcept1', 1 );
|
||||
|
||||
|
||||
dbg.Stop;
|
||||
finally
|
||||
dbg.Done;
|
||||
CleanGdb;
|
||||
dbg.Free;
|
||||
end;
|
||||
|
||||
AssertTestErrors;
|
||||
end;
|
||||
|
||||
procedure TTestExceptionOne.TestExceptionStepOverEx;
|
||||
var
|
||||
dbg: TGDBMIDebugger;
|
||||
|
||||
function StepIfAtLine(ATestName, ABrkName: String): Boolean;
|
||||
begin
|
||||
Result := True;
|
||||
if not IsAtLine(ABrkName) then
|
||||
exit;
|
||||
Debugger.LazDebugger.StepOver;
|
||||
TestTrue(ATestName+' finally entered at begin (not end) / '+ ABrkName, False, 0, 'ignore');
|
||||
AssertDebuggerState(dsPause, ATestName);
|
||||
debugln(['XXXXXXXXXXXXXXXXXXXXXXXX STEPPED from END LINE to begin??? ', ABrkName, ' ',ATestName]);
|
||||
end;
|
||||
|
||||
procedure ExpectEnterFinally(AName: String; ATestAppRecStep: Integer;
|
||||
ATestIgnoreRaise, ATestRaiseSkipped: Boolean;
|
||||
ATestIgnoreRaise_2, ATestRaiseSkipped_2: Boolean);
|
||||
var
|
||||
TstName: String;
|
||||
MyRaiseBrk: TDBGBreakPoint;
|
||||
begin
|
||||
TstName := AName + ' Run to raise';
|
||||
FGotExceptCount := 0;
|
||||
FContinue := ATestIgnoreRaise;
|
||||
|
||||
if ATestIgnoreRaise then begin
|
||||
MyRaiseBrk := Debugger.SetBreakPoint(Src, 'BrkMyRaise');
|
||||
dbg.Run;
|
||||
MyRaiseBrk.ReleaseReference;
|
||||
dbg.StepOver; // exception will be ignored => step to finally
|
||||
TestEquals(TstName+': Got 1 exceptions: ', 1, FGotExceptCount);
|
||||
end
|
||||
else begin
|
||||
dbg.Run;
|
||||
TestEquals(TstName+': Got 1 exceptions: ', 1, FGotExceptCount);
|
||||
TestLocation(TstName+': CurLine ', 'BrkMyRaise');
|
||||
dbg.StepOver;
|
||||
end;
|
||||
|
||||
TstName := AName + ' Run to Finally A';
|
||||
StepIfAtLine(TstName, 'BrkStep3Fin_A_END');
|
||||
TestLocation(TstName+': CurLine ', 'BrkStep3Fin_A', 1);
|
||||
|
||||
if (ATestAppRecStep = 1) and (not ATestRaiseSkipped) then
|
||||
ExpectEnterFinally(TstName+' INNER ', 0, ATestIgnoreRaise_2, ATestRaiseSkipped_2, False, False)
|
||||
else
|
||||
StepOverToLine(TstName, 'BrkStep3Fin_A_END', True);
|
||||
|
||||
TstName := AName + ' Run to Finally B';
|
||||
StepOverLeaveFinally(TstName); // Step to next finally
|
||||
StepIfAtLine(TstName, 'BrkStep3Fin_B_END');
|
||||
TestLocation(TstName+': CurLine ', 'BrkStep3Fin_B', 1);
|
||||
|
||||
//if (ATestAppRecStep = 2) and (not ATestRaiseSkipped) then
|
||||
// ExpectEnterFinally(TstName+' INNER ', 0, ATestIgnoreRaise_2, ATestRaiseSkipped_2, False, False)
|
||||
//else
|
||||
StepOverToLine(TstName, 'BrkStep3Fin_B_END', True);
|
||||
|
||||
TstName := AName + ' Run to Finally C';
|
||||
StepOverLeaveFinally(TstName); // Step to next finally
|
||||
StepIfAtLine(TstName, 'BrkStep3Fin_C_END');
|
||||
TestLocation(TstName+': CurLine ', 'BrkStep3Fin_C', 1);
|
||||
|
||||
if (ATestAppRecStep = 2) and (not ATestRaiseSkipped) then
|
||||
ExpectEnterFinally(TstName+' INNER ', 0, ATestIgnoreRaise_2, ATestRaiseSkipped_2, False, False)
|
||||
else
|
||||
StepOverToLine(TstName, 'BrkStep3Fin_C_END', True);
|
||||
|
||||
TstName := AName + ' Run to Finally A(outer)';
|
||||
StepOverLeaveFinally(TstName); // Step to next finally
|
||||
StepIfAtLine(TstName, 'BrkStep3FinOuter_A_END');
|
||||
TestLocation(TstName+': CurLine ', 'BrkStep3FinOuter_A', 1);
|
||||
|
||||
if (ATestAppRecStep = 3) and (not ATestRaiseSkipped) then
|
||||
ExpectEnterFinally(TstName+' INNER ', 0, ATestIgnoreRaise_2, ATestRaiseSkipped_2, False, False)
|
||||
else
|
||||
StepOverToLine(TstName, 'BrkStep3FinOuter_A_END', True);
|
||||
|
||||
TstName := AName + ' Run to Finally B(outer)';
|
||||
StepOverLeaveFinally(TstName); // Step to next finally
|
||||
StepIfAtLine(TstName, 'BrkStep3FinOuter_B_END');
|
||||
TestLocation(TstName+': CurLine ', 'BrkStep3FinOuter_B', 1);
|
||||
|
||||
//if (ATestAppRecStep = 5) and (not ATestRaiseSkipped) then
|
||||
// ExpectEnterFinally(TstName+' INNER ', 0, ATestIgnoreRaise_2, ATestRaiseSkipped_2, False, False)
|
||||
//else
|
||||
StepOverToLine(TstName, 'BrkStep3FinOuter_B_END', True);
|
||||
|
||||
TstName := AName + ' Run to Finally C(outer)';
|
||||
StepOverLeaveFinally(TstName); // Step to next finally
|
||||
StepIfAtLine(TstName, 'BrkStep3FinOuter_C_END');
|
||||
TestLocation(TstName+': CurLine ', 'BrkStep3FinOuter_C', 1);
|
||||
|
||||
if (ATestAppRecStep = 4) and (not ATestRaiseSkipped) then
|
||||
ExpectEnterFinally(TstName+' INNER ', 0, ATestIgnoreRaise_2, ATestRaiseSkipped_2, False, False)
|
||||
else
|
||||
StepOverToLine(TstName,'BrkStep3FinOuter_C_END', True);
|
||||
end;
|
||||
|
||||
procedure ExpectNestedExcept(AName: String);
|
||||
var
|
||||
TstName: String;
|
||||
begin
|
||||
TstName := AName + ' Run to raise';
|
||||
FGotExceptCount := 0;
|
||||
FContinue := False;
|
||||
dbg.Run;
|
||||
TestEquals(TstName+': Got 1 exceptions: ', 1, FGotExceptCount);
|
||||
TestLocation(TstName+': CurLine ', 'BrkMyRaise');
|
||||
|
||||
TstName := AName + ' Run to except fin';
|
||||
dbg.StepOver; // Step to fin
|
||||
StepIfAtLine(TstName, 'BrkStepNestedExcept_Finally_END');
|
||||
TestLocation(TstName+': CurLine ', 'BrkStepNestedExcept_Finally', 1);
|
||||
|
||||
// NESTED
|
||||
TstName := AName + ' Run to raise nested';
|
||||
FGotExceptCount := 0;
|
||||
FContinue := False;
|
||||
dbg.Run;
|
||||
TestEquals(TstName+': Got 1 exceptions: ', 1, FGotExceptCount);
|
||||
TestLocation(TstName+': CurLine ', 'BrkMyRaise');
|
||||
|
||||
TstName := AName + ' Run to except fin nested';
|
||||
dbg.StepOver; // Step to fin
|
||||
StepIfAtLine(TstName, 'BrkStepNestedExcept_Finally_END');
|
||||
TestLocation(TstName+': CurLine ', 'BrkStepNestedExcept_Finally', 1);
|
||||
|
||||
StepOverToLine(TstName,'BrkStepNestedExcept_Finally_END', True);
|
||||
|
||||
TstName := AName + ' Run to except nested';
|
||||
StepOverLeaveFinally(TstName);
|
||||
StepIfAtLine(TstName, 'BrkStepNestedExcept_END');
|
||||
TestLocation(TstName+': CurLine ', 'BrkStepNestedExcept', 1);
|
||||
|
||||
StepOverToLine(TstName,'BrkStepNestedExcept_END', True);
|
||||
// END NESTED
|
||||
|
||||
TstName := AName + ' Run back except fin';
|
||||
dbg.StepOver; // Step back to end
|
||||
dbg.StepOver; // Step back to finaly
|
||||
if not IsAtLine('BrkStepNestedExcept_Finally_AFTER') then dbg.StepOver; // sometimes need extra steps at "end"
|
||||
if not IsAtLine('BrkStepNestedExcept_Finally_AFTER') then dbg.StepOver; // sometimes need extra steps at "end"
|
||||
TestLocation(TstName+': CurLine ', 'BrkStepNestedExcept_Finally_AFTER', 1);
|
||||
|
||||
StepOverToLine(TstName,'BrkStepNestedExcept_Finally_END', True);
|
||||
|
||||
TstName := AName + ' Run to except';
|
||||
StepOverLeaveFinally(TstName);
|
||||
StepIfAtLine(TstName, 'BrkStepNestedExcept_END');
|
||||
TestLocation(TstName+': CurLine ', 'BrkStepNestedExcept', 1);
|
||||
|
||||
//StepOverToLine(TstName,'BrkStepNestedExcept_END', True);
|
||||
dbg.StepOut; // Step out
|
||||
end;
|
||||
|
||||
procedure ExpectNestedExcept_Ignore(AName: String);
|
||||
var
|
||||
TstName: String;
|
||||
begin
|
||||
TstName := AName + ' Run to raise';
|
||||
FGotExceptCount := 0;
|
||||
FContinue := False;
|
||||
dbg.Run;
|
||||
TestEquals(TstName+': Got 1 exceptions: ', 1, FGotExceptCount);
|
||||
TestLocation(TstName+': CurLine ', 'BrkMyRaise');
|
||||
|
||||
TstName := AName + ' Run to except fin';
|
||||
dbg.StepOver; // Step to fin
|
||||
StepIfAtLine(TstName, 'BrkStepNestedExcept_Finally_END');
|
||||
TestLocation(TstName+': CurLine ', 'BrkStepNestedExcept_Finally', 1);
|
||||
|
||||
// NESTED
|
||||
TstName := AName + ' Step over raise nested';
|
||||
FGotExceptCount := 0;
|
||||
FContinue := True;
|
||||
StepOverToLine(TstName,'BrkStepNestedExcept_Finally_BEFORE', True);
|
||||
dbg.StepOver;
|
||||
TestEquals(TstName+': Got 1 exceptions: ', 1, FGotExceptCount);
|
||||
TestLocation(TstName+': CurLine ', 'BrkStepNestedExcept_Finally_AFTER', 1);
|
||||
|
||||
StepOverToLine(TstName,'BrkStepNestedExcept_Finally_END', True);
|
||||
|
||||
TstName := AName + ' Run to except';
|
||||
StepOverLeaveFinally(TstName);
|
||||
StepIfAtLine(TstName, 'BrkStepNestedExcept_END');
|
||||
TestLocation(TstName+': CurLine ', 'BrkStepNestedExcept', 1);
|
||||
|
||||
//StepOverToLine(TstName,'BrkStepNestedExcept_END', True);
|
||||
dbg.StepOut; // Step out
|
||||
|
||||
end;
|
||||
|
||||
var
|
||||
ExeName, TstName, LName: String;
|
||||
TestAppRecRaise, TestAppRecStep: Integer;
|
||||
begin
|
||||
if SkipTest then exit;
|
||||
if not TestControlCanTest(ControlTestExceptionOneExceptionStepOverEx) then exit;
|
||||
ClearTestErrors;
|
||||
|
||||
Src := GetCommonSourceFor(AppDir + 'ExceptTestPrg.pas');
|
||||
TestCompile(Src, ExeName);
|
||||
|
||||
dbg := StartGDB(AppDir, ExeName);
|
||||
try
|
||||
dbg.Exceptions.Add('MyExceptionIgnore').Enabled := False;
|
||||
dbg.OnException := @DoDebuggerException;
|
||||
dbg.OnCurrent := @DoCurrent;
|
||||
|
||||
for TestAppRecRaise := 0 to 2 do
|
||||
for TestAppRecStep := 0 to 4 do
|
||||
if (TestAppRecRaise = 0) or (TestAppRecStep in [0,1,4]) then
|
||||
begin
|
||||
LName := Format('[RecRaise=%d / RecStep=%d] ', [TestAppRecRaise, TestAppRecStep]);
|
||||
ExpectEnterFinally(LName, TestAppRecStep,
|
||||
False, False,
|
||||
TestAppRecRaise = 1, TestAppRecRaise = 2);
|
||||
|
||||
TstName := LName + ' Run to Except (Main)';
|
||||
StepOverLeaveFinally(TstName);
|
||||
TestLocation(TstName+': CurLine ', 'BrkStepMainExcept1', 1);
|
||||
|
||||
TstName := LName + ' Step to After Except (Main)';
|
||||
dbg.StepOver;
|
||||
StepOverToLine(TstName,'BrkStepMainAfterExcept1', True);
|
||||
TestLocation(TstName+': CurLine ', 'BrkStepMainAfterExcept1', 1);
|
||||
end;
|
||||
|
||||
ExpectNestedExcept('Nested Except 1');
|
||||
|
||||
ExpectNestedExcept_Ignore('Nested Except Ignore');
|
||||
|
||||
dbg.Stop;
|
||||
finally
|
||||
dbg.Done;
|
||||
CleanGdb;
|
||||
dbg.Free;
|
||||
end;
|
||||
|
||||
AssertTestErrors;
|
||||
end;
|
||||
|
||||
initialization
|
||||
RegisterDbgTest(TTestExceptionAddrDirect);
|
||||
RegisterDbgTest(TTestExceptionAddrInDirect);
|
||||
@ -592,5 +1002,7 @@ initialization
|
||||
ControlTestExceptionOneException := TestControlRegisterTest('Exception', ControlTestExceptionOne);
|
||||
ControlTestExceptionOneExceptionStepOut := TestControlRegisterTest('ExceptionStepOut', ControlTestExceptionOne);
|
||||
ControlTestExceptionOneExceptionStepOver := TestControlRegisterTest('ExceptionStepOver', ControlTestExceptionOne);
|
||||
ControlTestExceptionOneExceptionStepOutEx := TestControlRegisterTest('ExceptionStepOutEx', ControlTestExceptionOne);
|
||||
ControlTestExceptionOneExceptionStepOverEx := TestControlRegisterTest('ExceptionStepOverEx', ControlTestExceptionOne);
|
||||
end.
|
||||
|
||||
|
@ -83,7 +83,7 @@ begin
|
||||
if (i < 0) or (FBreakPoints.Objects[i] = nil) then
|
||||
raise Exception.Create('Break unknown '+AName);
|
||||
Result := Integer(PtrInt(FBreakPoints.Objects[i]));
|
||||
TestLogger.DebugLn(['Break: ',AName, ' ',Result]);
|
||||
//TestLogger.DebugLn(['Break: ',AName, ' ',Result]);
|
||||
end;
|
||||
|
||||
function TCommonSource.GetOtherSrc(AName: String): TCommonSource;
|
||||
|
@ -119,7 +119,7 @@ type
|
||||
|
||||
procedure CleanAfterTestDone; virtual;
|
||||
|
||||
property LazDebugger: TDebuggerIntf read FLazDebugger;
|
||||
property LazDebugger: TDebuggerIntf read FLazDebugger write FLazDebugger;
|
||||
|
||||
property CallStack: TTestCallStackMonitor read FCallStack;
|
||||
property Disassembler: TBaseDisassembler read FDisassembler;
|
||||
|
Loading…
Reference in New Issue
Block a user