File: StepOverPrg.pas

package info (click to toggle)
lazarus 4.0%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 275,760 kB
  • sloc: pascal: 2,341,904; xml: 509,420; makefile: 348,726; cpp: 93,608; sh: 3,387; java: 609; perl: 297; sql: 222; ansic: 137
file content (137 lines) | stat: -rw-r--r-- 3,674 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
program StepOverPrg;
{$asmMode intel}
uses
  {$IFDEF UNIX}
  cthreads,
  {$ENDIF}
  sysutils, Classes;

type

  { TTestThread1 }

  TTestThread1 = class(TThread)
    procedure Execute; override;
  end;


var
  x, BreakDummy: Integer;
  T1, T1Interfere: Integer;
  T1Stop: Boolean;


label
testasmlbl1, testasmlbl2;

Procedure MyNorm;
begin
  x := 1;
end;

Procedure StepOverEnd(a: integer); // USED FOR line lookup // do not add lines
var
  b: integer;
begin                                  // TEST_BREAKPOINT=StepOverBegin
  b := a;
// 3 empty lines in function (for line lookup test)
//
// end returns to the same line
if a < 1 then StepOverEnd(a+1); end;   // TEST_BREAKPOINT=StepOverEnd


Procedure MyNested(ALvl: Integer = 0);
var
  a: integer;
begin
  if ALvl > 3 then exit; a := x;
  if ALvl = 0 then
    x := 1;  // TEST_BREAKPOINT=BrkNested
  x := 3; MyNested(ALvl + 1); x := 4; if ALvl = 0 then // only reach "AfterNested" in most outer recurse
    x := 2; // TEST_BREAKPOINT=AfterNested
  x := 1;
end;

Procedure MySleep;
begin
  Sleep(50);
end;

Procedure MyBrkDis;
begin
  x := 1;  // TEST_BREAKPOINT=BrkDisabled
end;

Procedure MyBrkHitCnt;
begin
  x := 1;  // TEST_BREAKPOINT=BrkHitCnt
end;

(* Try to step over a line, while another thread is also going through the line *)
Procedure MyInterfereByThread(a: Boolean = false);
  Procedure MyInterfereSleep;
  begin
    if a then Sleep(10); // threads do not stop / while the test waits here, other threads should hit the calling line
  end;
begin
  if a then
    x := 1; // TEST_BREAKPOINT=BrkInterfereByThread
  if a then InterLockedExchange(T1Interfere, 0); while (InterLockedExchangeAdd(T1Interfere,0)=0) do begin MyInterfereSleep; if not a then break; end;
  x := 1; // TEST_BREAKPOINT=AfterInterfereByThread

  InterLockedIncrement(T1Interfere); // Other threads will increment
end;

{ TTestThread1 }

procedure TTestThread1.Execute;
begin
  InterLockedIncrement(T1);
  while not (Terminated or T1Stop) do MyInterfereByThread;
  InterLockedDecrement(T1);
end;

begin

  x := 1;
  x := x + 1;     // TEST_BREAKPOINT=BrkStart
  x := x + 1; x := x + 2; x := x + 3;    // TEST_BREAKPOINT=AfterStep
  MyNorm();       // TEST_BREAKPOINT=AfterStepLongLine
  x := 1; MyNorm(); x := x + 1; MyNorm(); x := x + 1; MyNorm(); x := x + 1;      // TEST_BREAKPOINT=AfterStepProc
  MySleep();      // TEST_BREAKPOINT=AfterStepProcLong
  sleep(50);      // TEST_BREAKPOINT=AfterStepSleepProc
  MyBrkDis;       // TEST_BREAKPOINT=AfterStepSleep
  MyBrkHitCnt;    // TEST_BREAKPOINT=AfterStepBrkDis
  MyBrkDis;       // TEST_BREAKPOINT=AfterStepBrkHitCnt
  x := 1;         // TEST_BREAKPOINT=AfterStepBrkDisAgain
  x := 1;
  MyNested; // TEST_BREAKPOINT=CallNested


  T1 := 0;
  T1Stop := False;
  TTestThread1.Create(False); while not (InterLockedExchangeAdd(T1,0)=1) do x:=1;  // TEST_BREAKPOINT=BrkThreadCreateInStep
  x := 1;         // TEST_BREAKPOINT=AfterThreadCreateInStep

  (* Prepare for threads to interfare with the hidden breakpoint *)
  // create a few threads to interfer
  TTestThread1.Create(False); TTestThread1.Create(False); TTestThread1.Create(False);
  TTestThread1.Create(False); TTestThread1.Create(False); TTestThread1.Create(False);
  while not (InterLockedExchangeAdd(T1,0)>=5) do sleep(10);  // at least 5 running

  MyInterfereByThread(True);
  T1Stop := True;

  while not (InterLockedExchangeAdd(T1,0)<=1) do x:=1;  // TEST_BREAKPOINT=BrkThreadExitInStep
  x := 1;         // TEST_BREAKPOINT=AfterThreadExitInStep

  //sleep(500);
  BreakDummy := 1;


  StepOverEnd(0); // TEST_BREAKPOINT=CallStepOverEnd
  BreakDummy := 1;  // TEST_BREAKPOINT=AfterCallStepOverEnd
  BreakDummy := 1;

end.