8
SysUtils, fpcunit, testutils, testregistry, TestGDBMIControl,
9
TestBase, Debugger, GDBMIDebugger, LCLProc, TestWatches;
13
{ TTestBrkGDBMIDebugger }
15
TTestBrkGDBMIDebugger = class(TGDBMIDebugger)
17
procedure TestInterruptTarget;
23
TTestBreakPoint = class(TGDBTestCase)
27
FBrkErr: TDBGBreakPoint;
29
function DoGetFeedBack(Sender: TObject; const AText, AInfo: String;
30
AType: TDBGFeedbackType; AButtons: TDBGFeedbackResults): TDBGFeedbackResult;
31
function GdbClass: TGDBMIDebuggerClass; override;
32
procedure DoCurrent(Sender: TObject; const ALocation: TDBGLocationRec);
34
// Due to a linker error breakpoints can point to invalid addresses
35
procedure TestStartMethod;
36
procedure TestBadAddrBreakpoint;
37
procedure TestInteruptWhilePaused;
42
procedure TTestBrkGDBMIDebugger.TestInterruptTarget;
47
{ TTestBrkGDBMIDebugger }
52
procedure TTestBreakPoint.DoCurrent(Sender: TObject; const ALocation: TDBGLocationRec);
54
FCurFile := ALocation.SrcFile;
55
FCurLine := ALocation.SrcLine;
58
procedure TTestBreakPoint.TestStartMethod;
61
TestExeName, s: string;
62
i: TGDBMIDebuggerStartBreak;
65
if SkipTest then exit;
66
if not TestControlForm.CheckListBox1.Checked[TestControlForm.CheckListBox1.Items.IndexOf('TTestBreakPoint')] then exit;
67
if not TestControlForm.CheckListBox1.Checked[TestControlForm.CheckListBox1.Items.IndexOf(' TTestBreakPoint.StartMethod')] then exit;
71
TestCompile(AppDir + 'WatchesPrg.pas', TestExeName);
73
for i := Low(TGDBMIDebuggerStartBreak) to high(TGDBMIDebuggerStartBreak) do begin
77
dbg := StartGDB(AppDir, TestExeName);
78
dbg.OnCurrent := @DoCurrent;
79
TGDBMIDebuggerProperties(dbg.GetProperties).InternalStartBreak := i;
80
with dbg.BreakPoints.Add('WatchesPrg.pas', BREAK_LINE_FOOFUNC) do begin
81
InitialEnabled := True;
88
case DebuggerInfo.Version of
89
070400..070499: if i = gdsbAddZero then IgnoreRes:= 'gdb 7.4.x does not work with gdsbAddZero';
92
TestTrue(s+' not in error state 1', dbg.State <> dsError, 0, IgnoreRes);
93
TestTrue(s+' at break', FCurLine = BREAK_LINE_FOOFUNC, 0, IgnoreRes);
95
TGDBMIDebuggerProperties(dbg.GetProperties).InternalStartBreak := gdsbDefault;
106
function TTestBreakPoint.DoGetFeedBack(Sender: TObject; const AText, AInfo: String;
107
AType: TDBGFeedbackType; AButtons: TDBGFeedbackResults): TDBGFeedbackResult;
110
ReleaseRefAndNil(FBrkErr);
113
function TTestBreakPoint.GdbClass: TGDBMIDebuggerClass;
115
Result := TTestBrkGDBMIDebugger;
118
procedure TTestBreakPoint.TestBadAddrBreakpoint;
121
dbg: TTestBrkGDBMIDebugger;
124
if SkipTest then exit;
125
if not TestControlForm.CheckListBox1.Checked[TestControlForm.CheckListBox1.Items.IndexOf('TTestBreakPoint')] then exit;
126
if not TestControlForm.CheckListBox1.Checked[TestControlForm.CheckListBox1.Items.IndexOf(' TTestBreakPoint.BadAddr')] then exit;
130
TestCompile(AppDir + 'WatchesPrg.pas', TestExeName);
132
dbg := TTestBrkGDBMIDebugger(StartGDB(AppDir, TestExeName));
133
dbg.OnCurrent := @DoCurrent;
134
with dbg.BreakPoints.Add('WatchesPrg.pas', BREAK_LINE_FOOFUNC) do begin
135
InitialEnabled := True;
139
dbg.OnFeedback := @DoGetFeedBack;
143
FBrkErr := dbg.BreakPoints.Add(TDBGPtr(200));
144
with FBrkErr do begin
145
InitialEnabled := True;
148
TestTrue('not in error state 1', dbg.State <> dsError);
152
TestTrue('not in error state 2', dbg.State <> dsError);
153
//TestTrue('gone next line 2', i <> FCurLine);
157
TestTrue('not in error state 3', dbg.State <> dsError);
158
//TestTrue('gone next line 3', i <> FCurLine);
162
TestTrue('not in error state 4', dbg.State <> dsError);
163
//TestTrue('gone next line 4', i <> FCurLine);
174
procedure TTestBreakPoint.TestInteruptWhilePaused;
176
TestExeName, Err, IgnoreRes: string;
177
dbg: TTestBrkGDBMIDebugger;
180
if SkipTest then exit;
181
if not TestControlForm.CheckListBox1.Checked[TestControlForm.CheckListBox1.Items.IndexOf('TTestBreakPoint')] then exit;
182
if not TestControlForm.CheckListBox1.Checked[TestControlForm.CheckListBox1.Items.IndexOf(' TTestBreakPoint.BadInterrupt')] then exit;
184
(* Trigger a InterruptTarget while paused.
185
Test if the app can continue, and reach it normal exit somehow (even if multiply interupts must be skipped)
191
TestCompile(AppDir + 'WatchesPrg.pas', TestExeName, '_wsleep', ' -dWITH_SLEEP ');
194
LogToFile(LineEnding+'###################### with pause -- 1 break ########################'+LineEnding+LineEnding);
196
dbg := TTestBrkGDBMIDebugger(StartGDB(AppDir, TestExeName));
197
dbg.OnCurrent := @DoCurrent;
198
with dbg.BreakPoints.Add('WatchesPrg.pas', BREAK_LINE_FOOFUNC) do begin
199
InitialEnabled := True;
203
dbg.OnFeedback := @DoGetFeedBack;
207
if dbg.GetLocation.SrcLine <> BREAK_LINE_FOOFUNC
208
then Err := Err + 'Never reached breakpoint to start with';
209
if dbg.State <> dsPause
210
then Err := Err + 'Never entered dsPause to start with';
214
LogToFile('##### INTERRUPT #####');
215
dbg.TestInterruptTarget;
218
if dbg.State = dsError
219
then Err := Err + 'Enterred dsError after 1st exec-continue';
220
if dbg.State = dsStop
221
then Err := Err + 'Enterred dsStop after 1st exec-continue';
223
// try to skip to next break
224
if (dbg.State = dsPause) and (dbg.GetLocation.SrcLine <> BREAK_LINE_FOOFUNC)
226
if (dbg.State = dsPause) and (dbg.GetLocation.SrcLine <> BREAK_LINE_FOOFUNC)
229
if dbg.State = dsError
230
then Err := Err + 'Enterred dsError before reaching break the 2nd time';
231
if dbg.State = dsStop
232
then Err := Err + 'Enterred dsStop before reaching break the 2nd time';
233
if dbg.GetLocation.SrcLine <> BREAK_LINE_FOOFUNC
234
then Err := Err + 'Did not reached breakpoint for the 2nd time';
238
if (dbg.State = dsPause)
239
then dbg.Run; // got the break really late
240
if (dbg.State = dsPause)
241
then dbg.Run; // got the break really late
243
if dbg.State <> dsStop
244
then Err := Err + 'Never reached final stop';
246
TestEquals('Passed pause run', '', Err);
253
if TestControlForm.CheckListBox1.Checked[TestControlForm.CheckListBox1.Items.IndexOf(' TTestBreakPoint.BadInterrupt.All')] then begin
255
LogToFile(LineEnding+'###################### with pause -- 2 breaks ########################'+LineEnding+LineEnding);
257
dbg := TTestBrkGDBMIDebugger(StartGDB(AppDir, TestExeName));
258
dbg.OnCurrent := @DoCurrent;
259
with dbg.BreakPoints.Add('WatchesPrg.pas', BREAK_LINE_FOOFUNC) do begin
260
InitialEnabled := True;
263
with dbg.BreakPoints.Add('WatchesPrg.pas', BREAK_LINE_FOOFUNC_NEST) do begin
264
InitialEnabled := True;
268
dbg.OnFeedback := @DoGetFeedBack;
274
if dbg.GetLocation.SrcLine <> BREAK_LINE_FOOFUNC
275
then Err := Err + 'Never reached breakpoint to start with';
276
if dbg.State <> dsPause
277
then Err := Err + 'Never entered dsPause to start with';
281
LogToFile('##### INTERRUPT #####');
282
dbg.TestInterruptTarget;
285
if dbg.State = dsError
286
then Err := Err + 'Enterred dsError after 1st exec-continue';
287
if dbg.State = dsStop
288
then Err := Err + 'Enterred dsStop after 1st exec-continue';
290
// try to skip to next break
291
if (dbg.State = dsPause) and (dbg.GetLocation.SrcLine <> BREAK_LINE_FOOFUNC_NEST)
293
if (dbg.State = dsPause) and (dbg.GetLocation.SrcLine <> BREAK_LINE_FOOFUNC_NEST)
296
if dbg.State = dsError
297
then Err := Err + 'Enterred dsError before reaching nest break the 2nd time';
298
if dbg.State = dsStop
299
then Err := Err + 'Enterred dsStop before reaching nest break the 2nd time';
300
if dbg.GetLocation.SrcLine <> BREAK_LINE_FOOFUNC_NEST
301
then Err := Err + 'Did not reached best breakpoint for the 2nd time';
305
// try to skip to next break
306
if (dbg.State = dsPause) and (dbg.GetLocation.SrcLine <> BREAK_LINE_FOOFUNC)
308
if (dbg.State = dsPause) and (dbg.GetLocation.SrcLine <> BREAK_LINE_FOOFUNC)
311
if dbg.State = dsError
312
then Err := Err + 'Enterred dsError before reaching break the 2nd time';
313
if dbg.State = dsStop
314
then Err := Err + 'Enterred dsStop before reaching break the 2nd time';
315
if dbg.GetLocation.SrcLine <> BREAK_LINE_FOOFUNC
316
then Err := Err + 'Did not reached breakpoint for the 2nd time';
320
if (dbg.State = dsPause)
321
then dbg.Run; // got the break really late
322
if (dbg.State = dsPause)
323
then dbg.Run; // got the break really late
325
if dbg.State <> dsStop
326
then Err := Err + 'Never reached final stop';
328
TestEquals('Passed pause run 2 breaks', '', Err);
335
TestCompile(AppDir + 'WatchesPrg.pas', TestExeName);
339
if TestControlForm.CheckListBox1.Checked[TestControlForm.CheckListBox1.Items.IndexOf(' TTestBreakPoint.BadInterrupt.All')]
340
then m := 5; // run extra tests of Passed none-pause run
343
for i := 1 to m do begin
345
LogToFile(LineEnding+'###################### withOUT pause -- NO stepping ########################'+LineEnding+LineEnding);
346
dbg := TTestBrkGDBMIDebugger(StartGDB(AppDir, TestExeName));
347
dbg.OnCurrent := @DoCurrent;
348
with dbg.BreakPoints.Add('WatchesPrg.pas', BREAK_LINE_FOOFUNC) do begin
349
InitialEnabled := True;
353
dbg.OnFeedback := @DoGetFeedBack;
357
if dbg.GetLocation.SrcLine <> BREAK_LINE_FOOFUNC
358
then Err := Err + 'Never reached breakpoint to start with';
359
if dbg.State <> dsPause
360
then Err := Err + 'Never entered dsPause to start with';
364
LogToFile('##### INTERRUPT #####');
365
dbg.TestInterruptTarget;
368
if dbg.State = dsError
369
then Err := Err + 'Enterred dsError after 1st exec-continue';
370
if dbg.State = dsStop
371
then Err := Err + 'Enterred dsStop after 1st exec-continue';
373
// try to skip to next break
374
if (dbg.State = dsPause) and (dbg.GetLocation.SrcLine <> BREAK_LINE_FOOFUNC)
376
if (dbg.State = dsPause) and (dbg.GetLocation.SrcLine <> BREAK_LINE_FOOFUNC)
379
if dbg.State = dsError
380
then Err := Err + 'Enterred dsError before reaching break the 2nd time';
381
if dbg.State = dsStop
382
then Err := Err + 'Enterred dsStop before reaching break the 2nd time';
383
if dbg.GetLocation.SrcLine <> BREAK_LINE_FOOFUNC
384
then Err := Err + 'Did not reached breakpoint for the 2nd time';
388
if (dbg.State = dsPause)
389
then dbg.Run; // got the break really late
390
if (dbg.State = dsPause)
391
then dbg.Run; // got the break really late
393
if dbg.State <> dsStop
394
then Err := Err + 'Never reached final stop';
402
case DebuggerInfo.Version of
403
0..069999: IgnoreRes:= 'all gdb 6.x may or may not fail';
404
070000: IgnoreRes:= 'gdb 7.0.0 may or may not fail';
405
// 7.0.50 seems to always pass
406
// 7.1.x seems to always pass
407
// 7.2.x seems to always pass
408
070300..070399: IgnoreRes:= 'gdb 7.3.x may or may not fail';
409
070400..070499: IgnoreRes:= 'gdb 7.4.x may or may not fail';
411
TestEquals('Passed none-pause run', '', Err, 0, IgnoreRes);
414
if TestControlForm.CheckListBox1.Checked[TestControlForm.CheckListBox1.Items.IndexOf(' TTestBreakPoint.BadInterrupt.All')] then begin
417
LogToFile(LineEnding+'###################### withOUT pause -- with stepping ########################'+LineEnding+LineEnding);
419
dbg := TTestBrkGDBMIDebugger(StartGDB(AppDir, TestExeName));
420
dbg.OnCurrent := @DoCurrent;
421
with dbg.BreakPoints.Add('WatchesPrg.pas', BREAK_LINE_FOOFUNC) do begin
422
InitialEnabled := True;
426
dbg.OnFeedback := @DoGetFeedBack;
430
if dbg.GetLocation.SrcLine <> BREAK_LINE_FOOFUNC
431
then Err := Err + 'Never reached breakpoint to start with';
432
if dbg.State <> dsPause
433
then Err := Err + 'Never entered dsPause to start with';
437
LogToFile('##### INTERRUPT #####');
438
dbg.TestInterruptTarget;
441
if dbg.State = dsError
442
then Err := Err + 'Enterred dsError after 1st exec-continue';
443
if dbg.State = dsStop
444
then Err := Err + 'Enterred dsStop after 1st exec-continue';
446
// try to skip to next break
447
if (dbg.State = dsPause) and (dbg.GetLocation.SrcLine <> BREAK_LINE_FOOFUNC)
449
if (dbg.State = dsPause) and (dbg.GetLocation.SrcLine <> BREAK_LINE_FOOFUNC)
452
if dbg.State = dsError
453
then Err := Err + 'Enterred dsError before reaching break the 2nd time';
454
if dbg.State = dsStop
455
then Err := Err + 'Enterred dsStop before reaching break the 2nd time';
456
if dbg.GetLocation.SrcLine <> BREAK_LINE_FOOFUNC
457
then Err := Err + 'Did not reached breakpoint for the 2nd time';
461
if (dbg.State = dsPause)
462
then dbg.Run; // got the break really late
463
if (dbg.State = dsPause)
464
then dbg.Run; // got the break really late
466
if dbg.State <> dsStop
467
then Err := Err + 'Never reached final stop';
469
TestEquals('Passed none-pause run with steps', '', Err);
481
RegisterDbgTest(TTestBreakPoint);