Package: Breakpoint

Breakpoint

nameinstructionbranchcomplexitylinemethod
Breakpoint(ILexLocation)
M: 0 C: 21
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 8
100%
M: 0 C: 1
100%
Breakpoint(ILexLocation, int, String)
M: 84 C: 0
0%
M: 7 C: 0
0%
M: 6 C: 0
0%
M: 26 C: 0
0%
M: 1 C: 0
0%
catchReturn(Context)
M: 8 C: 8
50%
M: 5 C: 1
17%
M: 3 C: 1
25%
M: 0 C: 2
100%
M: 0 C: 1
100%
check(ILexLocation, Context)
M: 34 C: 23
40%
M: 15 C: 3
17%
M: 8 C: 2
20%
M: 8 C: 7
47%
M: 0 C: 1
100%
clearHits()
M: 4 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
enterDebugger(Context)
M: 25 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 7 C: 0
0%
M: 1 C: 0
0%
isAboveNext(Context)
M: 18 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 6 C: 0
0%
M: 1 C: 0
0%
isContinue(Context)
M: 16 C: 0
0%
M: 6 C: 0
0%
M: 4 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
isEnabled()
M: 3 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
isOutOrBelow(Context)
M: 17 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 6 C: 0
0%
M: 1 C: 0
0%
print(String)
M: 6 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 3 C: 0
0%
M: 1 C: 0
0%
println(String)
M: 4 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
readHitCondition(LexTokenReader, BreakpointCondition)
M: 27 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 5 C: 0
0%
M: 1 C: 0
0%
setEnabled(boolean)
M: 4 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
stoppedAtString()
M: 15 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
toString()
M: 4 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%

Coverage

1: /*******************************************************************************
2: *
3: *        Copyright (C) 2008 Fujitsu Services Ltd.
4: *
5: *        Author: Nick Battle
6: *
7: *        This file is part of VDMJ.
8: *
9: *        VDMJ is free software: you can redistribute it and/or modify
10: *        it under the terms of the GNU General Public License as published by
11: *        the Free Software Foundation, either version 3 of the License, or
12: *        (at your option) any later version.
13: *
14: *        VDMJ is distributed in the hope that it will be useful,
15: *        but WITHOUT ANY WARRANTY; without even the implied warranty of
16: *        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17: *        GNU General Public License for more details.
18: *
19: *        You should have received a copy of the GNU General Public License
20: *        along with VDMJ. If not, see <http://www.gnu.org/licenses/>.
21: *
22: ******************************************************************************/
23:
24: package org.overture.interpreter.runtime;
25:
26: import java.io.Serializable;
27:
28: import org.overture.ast.expressions.PExp;
29: import org.overture.ast.intf.lex.ILexLocation;
30: import org.overture.ast.lex.Dialect;
31: import org.overture.ast.lex.LexIntegerToken;
32: import org.overture.ast.lex.LexToken;
33: import org.overture.ast.lex.VDMToken;
34: import org.overture.config.Settings;
35: import org.overture.interpreter.ast.expressions.BreakpointExpression;
36: import org.overture.interpreter.commands.DebuggerReader;
37: import org.overture.interpreter.messages.Console;
38: import org.overture.interpreter.scheduler.BasicSchedulableThread;
39: import org.overture.interpreter.scheduler.ISchedulableThread;
40: import org.overture.parser.lex.LexException;
41: import org.overture.parser.lex.LexTokenReader;
42: import org.overture.parser.syntax.ExpressionReader;
43: import org.overture.parser.syntax.ParserException;
44:
45: /**
46: * The root of the breakpoint class hierarchy.
47: */
48:
49: public class Breakpoint implements Serializable
50: {
51:         private static final long serialVersionUID = 1L;
52:
53:         /** The location of the breakpoint. */
54:         public final ILexLocation location;
55:         /** The number of the breakpoint. */
56:         public final int number;
57:         /** The condition or trace expression, in parsed form. */
58:         public final PExp parsed;
59:         /** The condition or trace expression, in raw form. */
60:         public final String trace;
61:
62:         /** The number of times this breakpoint has been reached. */
63:         public long hits = 0;
64:
65:         /** The condition saying if a the breakpoint is enabled */
66:         protected boolean enabled = true;
67:
68:         public Breakpoint(ILexLocation location)
69:         {
70:                 this.location = location;
71:                 this.number = 0;
72:                 this.trace = null;
73:                 this.parsed = null;
74:         }
75:
76:         /**
77:          * Create a breakpoint at the given location. The trace string is parsed to an Expression structure for subsequent
78:          * evaluation.
79:          *
80:          * @param location
81:          * The location of the breakpoint.
82:          * @param number
83:          * The number that appears in the "list" command.
84:          * @param trace
85:          * Any condition or trace expression.
86:          * @throws ParserException
87:          * @throws LexException
88:          */
89:
90:         public Breakpoint(ILexLocation location, int number, String trace)
91:                         throws ParserException, LexException
92:         {
93:                 this.location = location;
94:                 this.number = number;
95:                 this.trace = trace;
96:
97:•                if (trace != null)
98:                 {
99:                         LexTokenReader ltr = new LexTokenReader(trace, Settings.dialect);
100:
101:                         ltr.push();
102:                         LexToken tok = ltr.nextToken();
103:
104:•                        switch (tok.type)
105:                         {
106:                                 case EQUALS:
107:                                         parsed = readHitCondition(ltr, BreakpointCondition.EQ);
108:                                         break;
109:
110:                                 case GT:
111:                                         parsed = readHitCondition(ltr, BreakpointCondition.GT);
112:                                         break;
113:
114:                                 case GE:
115:                                         parsed = readHitCondition(ltr, BreakpointCondition.GE);
116:                                         break;
117:
118:                                 case MOD:
119:                                         parsed = readHitCondition(ltr, BreakpointCondition.MOD);
120:                                         break;
121:
122:                                 default:
123:                                         ltr.pop();
124:                                         ExpressionReader reader = new ExpressionReader(ltr);
125:                                         reader.setCurrentModule(location.getModule());
126:                                         parsed = reader.readExpression();
127:                                         break;
128:                         }
129:                 } else
130:                 {
131:                         parsed = null;
132:                 }
133:         }
134:
135:         private PExp readHitCondition(LexTokenReader ltr, BreakpointCondition cond)
136:                         throws ParserException, LexException
137:         {
138:                 LexToken arg = ltr.nextToken();
139:
140:•                if (arg.isNot(VDMToken.NUMBER))
141:                 {
142:                         throw new ParserException(2279, "Invalid breakpoint hit condition", location, 0);
143:                 }
144:
145:                 LexIntegerToken num = (LexIntegerToken) arg;
146:                 return new BreakpointExpression(this, cond, num.value);
147:         }
148:
149:         @Override
150:         public String toString()
151:         {
152:                 return location.toString();
153:         }
154:
155:         public String stoppedAtString()
156:         {
157:                 return "Stopped ["
158:                                 + BasicSchedulableThread.getThreadName(Thread.currentThread())
159:                                 + "] " + location;
160:         }
161:
162:         public void clearHits()
163:         {
164:                 hits = 0;
165:         }
166:
167:         /**
168:          * Check whether to stop. The implementation in Breakpoint is used to check for the "step" and "next" commands,
169:          * using the stepline, nextctxt and outctxt fields. If the current line is different to the last step line, and the
170:          * current context is not "above" the next context or the current context equals the out context or neither the next
171:          * or out context are set, a {@link Stoppoint} is created and its check method is called - which starts a
172:          * DebuggerReader session.
173:          *
174:          * @param execl
175:          * The execution location.
176:          * @param ctxt
177:          * The execution context.
178:          */
179:
180:         public void check(ILexLocation execl, Context ctxt)
181:         {
182:                 // skips if breakpoint is disabled
183:                 // if(!enabled){
184:                 // return;
185:                 // }
186:
187:                 location.hit();
188:                 hits++;
189:
190:                 ThreadState state = ctxt.threadState;
191:
192:•                if (Settings.dialect != Dialect.VDM_SL)
193:                 {
194:                         state.reschedule(ctxt, execl);
195:                 }
196:
197:•                if (state.stepline != null)
198:                 {
199:•                        if (execl.getStartLine() != state.stepline.getStartLine()) // NB just line, not pos
200:                         {
201:•                                if (state.nextctxt == null && state.outctxt == null
202:                                                 || state.nextctxt != null
203:•                                                && !isAboveNext(ctxt.getRoot())
204:•                                                || state.outctxt != null && isOutOrBelow(ctxt))
205:                                 {
206:                                         try
207:                                         {
208:                                                 enterDebugger(ctxt);
209:                                         }
210:                                         catch (DebuggerException e)
211:                                         {
212:                                                 throw e;
213:                                         }
214:                                 }
215:                         }
216:                 }
217:         }
218:         
219:         /**
220:          * Actually stop and enter the debugger. The method returns when the user asks to
221:          * continue or step the specification.
222:          *
223:          * @param ctxt
224:          */
225:         public void enterDebugger(Context ctxt)
226:         {
227:                 ISchedulableThread th = BasicSchedulableThread.getThread(Thread.currentThread());
228:
229:•                if (th != null)
230:                 {
231:                         th.suspendOthers();
232:                 }
233:
234:•                if (Settings.usingDBGP)
235:                 {
236:                         ctxt.threadState.dbgp.stopped(ctxt, this);
237:                 }
238:                 else
239:                 {
240:                         new DebuggerReader(Interpreter.getInstance(), this, ctxt).run();
241:                 }
242:         }
243:         
244:         /**
245:          * Test for whether an apply expression or operation call ought to catch a breakpoint
246:          * after the return from the call. This only happens if we step into the call, so that
247:          * when we step out it is clear where we're unwinding too, rather than jumping down
248:          * the stack some considerable distance.
249:          *
250:          * @param ctxt
251:          * @return
252:          */
253:         public boolean catchReturn(Context ctxt)
254:         {
255:                 ThreadState state = ctxt.threadState;
256:•                return state.stepline != null && state.nextctxt == null && state.outctxt == null;
257:         }
258:
259:         /**
260:          * True if the current context is in a "continue" state.
261:          *
262:          * @param ctxt
263:          * @return
264:          */
265:         public boolean isContinue(Context ctxt)
266:         {
267:                 ThreadState state = ctxt.threadState;
268:•                return state.stepline == null && state.nextctxt == null && state.outctxt == null;
269:         }
270:
271:         /**
272:          * True, if the context passed is above nextctxt. That means that the current context must have an "outer" chain
273:          * that reaches nextctxt.
274:          *
275:          * @param current
276:          * The context to test.
277:          * @return True if the current context is above nextctxt.
278:          */
279:
280:         private boolean isAboveNext(Context current)
281:         {
282:                 Context c = current.outer;
283:
284:•                while (c != null)
285:                 {
286:•                        if (c == current.threadState.nextctxt)
287:                         {
288:                                 return true;
289:                         }
290:                         c = c.outer;
291:                 }
292:
293:                 return false;
294:         }
295:
296:         /**
297:          * True, if the context passed is equal to or below outctxt. That means that outctxt must have an "outer" chain that
298:          * reaches current context.
299:          *
300:          * @param current
301:          * The context to test.
302:          * @return True if the current context is at or below outctxt.
303:          */
304:
305:         private boolean isOutOrBelow(Context current)
306:         {
307:                 Context c = current.threadState.outctxt;
308:
309:•                while (c != null)
310:                 {
311:•                        if (c == current)
312:                         {
313:                                 return true;
314:                         }
315:                         c = c.outer;
316:                 }
317:
318:                 return false;
319:         }
320:
321:         protected void print(String line)
322:         {
323:                 Console.out.print(line);
324:                 Console.out.flush();
325:         }
326:
327:         protected void println(String line)
328:         {
329:                 Console.out.println(line);
330:         }
331:
332:         public void setEnabled(boolean bool)
333:         {
334:                 this.enabled = bool;
335:         }
336:
337:         public boolean isEnabled()
338:         {
339:                 return this.enabled;
340:         }
341: }