Skip to content

Commit b0994e0

Browse files
committed
added enabling/disabling breakpoints support
1 parent 7fed271 commit b0994e0

File tree

7 files changed

+195
-38
lines changed

7 files changed

+195
-38
lines changed

src/org/rubyforge/debugcommons/ClassicDebuggerCommandFactory.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,15 @@ public String createReadThreads() {
8282
public String createLoad(String filename) {
8383
return "load " + filename;
8484
}
85-
85+
86+
public String createEnableBreakpoint(int index) {
87+
return null;
88+
}
89+
90+
public String createDisableBreakpoint(int index) {
91+
return null;
92+
}
93+
8694
public String createInspect(RubyFrame frame, String expression) {
8795
return "th " + frame.getThread().getId() + "; v inspect " + frame.getIndex() + " " + expression;
8896
}

src/org/rubyforge/debugcommons/ICommandFactory.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,5 +64,8 @@ public interface ICommandFactory {
6464
String createCatchOff();
6565

6666
String createLoad(String filename);
67-
67+
68+
String createEnableBreakpoint(int index);
69+
70+
String createDisableBreakpoint(int index);
6871
}

src/org/rubyforge/debugcommons/ReadersSupport.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ final class ReadersSupport {
5050
private static final String EXCEPTION_ELEMENT = "exception";
5151
private static final String BREAKPOINT_ADDED_ELEMENT = "breakpointAdded";
5252
private static final String BREAKPOINT_DELETED_ELEMENT = "breakpointDeleted";
53+
private static final String BREAKPOINT_ENABLED_ELEMENT = "breakpointEnabled";
54+
private static final String BREAKPOINT_DISABLED_ELEMENT = "breakpointDisabled";
5355
private static final String CONDITION_SET_ELEMENT = "conditionSet";
5456
private static final String CATCHPOINT_SET_ELEMENT = "catchpointSet";
5557

@@ -77,6 +79,8 @@ final class ReadersSupport {
7779
private final BlockingQueue<SuspensionPoint> suspensions;
7880
private final BlockingQueue<Integer> addedBreakpoints;
7981
private final BlockingQueue<Integer> removedBreakpoints;
82+
private final BlockingQueue<Integer> enabledBreakpoints;
83+
private final BlockingQueue<Integer> disabledBreakpoints;
8084
private final BlockingQueue<Integer> conditionSets;
8185
private final BlockingQueue<String> catchpointSets;
8286

@@ -95,6 +99,8 @@ final class ReadersSupport {
9599
this.suspensions = new LinkedBlockingQueue<SuspensionPoint>();
96100
this.addedBreakpoints = new LinkedBlockingQueue<Integer>();
97101
this.removedBreakpoints = new LinkedBlockingQueue<Integer>();
102+
this.enabledBreakpoints = new LinkedBlockingQueue<Integer>();
103+
this.disabledBreakpoints = new LinkedBlockingQueue<Integer>();
98104
this.conditionSets = new LinkedBlockingQueue<Integer>();
99105
this.catchpointSets = new LinkedBlockingQueue<String>();
100106
}
@@ -141,6 +147,10 @@ private void processElement(final XmlPullParser xpp) throws IOException, XmlPull
141147
addedBreakpoints.add(BreakpointAddedReader.readBreakpointNo(xpp));
142148
} else if (BREAKPOINT_DELETED_ELEMENT.equals(element)) {
143149
removedBreakpoints.add(BreakpointDeletedReader.readBreakpointNo(xpp));
150+
} else if (BREAKPOINT_ENABLED_ELEMENT.equals(element)) {
151+
enabledBreakpoints.add(BreakpointEnabledReader.readBreakpointNo(xpp));
152+
} else if (BREAKPOINT_DISABLED_ELEMENT.equals(element)) {
153+
disabledBreakpoints.add(BreakpointDisabledReader.readBreakpointNo(xpp));
144154
} else if (BREAKPOINT_ELEMENT.equals(element) || SUSPENDED_ELEMENT.equals(element) || EXCEPTION_ELEMENT.equals(element)) {
145155
SuspensionPoint sp = SuspensionReader.readSuspension(xpp);
146156
suspensions.add(sp);
@@ -199,6 +209,24 @@ RubyVariableInfo[] readVariables() throws RubyDebuggerException {
199209
int readAddedBreakpointNo() throws RubyDebuggerException {
200210
return poll(addedBreakpoints, "added breakpoint number");
201211
}
212+
213+
int readEnabledBreakpointNo(int breakpointID) throws RubyDebuggerException {
214+
int enabledID = poll(enabledBreakpoints, "breakpoint number of the enabled breakpoint (" + breakpointID + ")");
215+
if (enabledID != breakpointID) {
216+
throw new RubyDebuggerException("Unexpected breakpoint removed. " +
217+
"Received id: " + enabledID + ", expected: " + breakpointID);
218+
}
219+
return enabledID;
220+
}
221+
222+
int readDisabledBreakpointNo(int breakpointID) throws RubyDebuggerException {
223+
int disabledID = poll(disabledBreakpoints, "breakpoint number of the disabled breakpoint (" + breakpointID + ")");
224+
if (disabledID != breakpointID) {
225+
throw new RubyDebuggerException("Unexpected breakpoint removed. " +
226+
"Received id: " + disabledID + ", expected: " + breakpointID);
227+
}
228+
return disabledID;
229+
}
202230

203231
int readConditionSet() throws RubyDebuggerException {
204232
return poll(conditionSets, "breakpoint number of the set condition");

src/org/rubyforge/debugcommons/RubyDebugCommandFactory.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,14 @@ public String createAddBreakpoint(String file, int line) {
9393
setBreakPointCommand.append(line);
9494
return setBreakPointCommand.toString();
9595
}
96+
97+
public String createEnableBreakpoint(int index) {
98+
return "enable " + index;
99+
}
100+
101+
public String createDisableBreakpoint(int index) {
102+
return "disable " + index;
103+
}
96104

97105
public String createRemoveBreakpoint(int index) {
98106
return "delete " + index;

src/org/rubyforge/debugcommons/RubyDebuggerProxy.java

Lines changed: 90 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import java.net.Socket;
2929
import java.util.HashMap;
3030
import java.util.HashSet;
31-
import java.util.Iterator;
3231
import java.util.List;
3332
import java.util.Map;
3433
import java.util.Set;
@@ -199,44 +198,95 @@ public synchronized void addBreakpoint(final IRubyBreakpoint breakpoint) {
199198
return;
200199
}
201200
assert breakpoint != null : "breakpoint cannot be null";
202-
if (breakpoint.isEnabled()) {
203-
try {
204-
if (breakpoint instanceof IRubyLineBreakpoint) {
205-
IRubyLineBreakpoint lineBreakpoint = (IRubyLineBreakpoint) breakpoint;
206-
String command = commandFactory.createAddBreakpoint(
207-
lineBreakpoint.getFilePath(), lineBreakpoint.getLineNumber());
208-
sendCommand(command);
209-
Integer id = getReadersSupport().readAddedBreakpointNo();
210-
String condition = lineBreakpoint.getCondition();
211-
if (condition != null && supportsCondition) {
212-
command = commandFactory.createSetCondition(id, condition);
213-
if (command != null) {
214-
sendCommand(command);
215-
getReadersSupport().readConditionSet(); // read response
216-
} else {
217-
LOGGER.info("conditional breakpoints are not supported by backend");
218-
}
219-
}
220-
breakpointsIDs.put(id, lineBreakpoint);
221-
} else if (breakpoint instanceof IRubyExceptionBreakpoint) {
222-
IRubyExceptionBreakpoint excBreakpoint = (IRubyExceptionBreakpoint) breakpoint;
223-
// just 're-enable' if contained in removedCatchpoints
224-
if (!removedCatchpoints.remove(excBreakpoint.getException())) {
225-
String command = commandFactory.createCatchOn(excBreakpoint);
201+
try {
202+
if (breakpoint instanceof IRubyLineBreakpoint) {
203+
IRubyLineBreakpoint lineBreakpoint = (IRubyLineBreakpoint) breakpoint;
204+
String command = commandFactory.createAddBreakpoint(
205+
lineBreakpoint.getFilePath(), lineBreakpoint.getLineNumber());
206+
sendCommand(command);
207+
Integer id = getReadersSupport().readAddedBreakpointNo();
208+
String condition = lineBreakpoint.getCondition();
209+
if (condition != null && supportsCondition) {
210+
command = commandFactory.createSetCondition(id, condition);
211+
if (command != null) {
226212
sendCommand(command);
227-
getReadersSupport().readCatchpointSet(); // read response
213+
getReadersSupport().readConditionSet(); // read response
214+
} else {
215+
LOGGER.info("conditional breakpoints are not supported by backend");
228216
}
217+
}
218+
if (!breakpoint.isEnabled()) {
219+
disableBreakpoint(breakpoint);
220+
}
221+
breakpointsIDs.put(id, lineBreakpoint);
222+
} else if (breakpoint instanceof IRubyExceptionBreakpoint) {
223+
IRubyExceptionBreakpoint excBreakpoint = (IRubyExceptionBreakpoint) breakpoint;
224+
// just 're-enable' if contained in removedCatchpoints
225+
if (!removedCatchpoints.remove(excBreakpoint.getException())) {
226+
String command = commandFactory.createCatchOn(excBreakpoint);
227+
sendCommand(command);
228+
getReadersSupport().readCatchpointSet(); // read response
229+
}
230+
} else {
231+
throw new IllegalArgumentException("Unknown breakpoint type: " + breakpoint);
232+
}
233+
} catch (final RubyDebuggerException ex) {
234+
if (isReady()) {
235+
LOGGER.log(Level.WARNING, "Cannot add breakpoint to: " + getDebugTarget(), ex);
236+
}
237+
}
238+
}
239+
240+
private void disableBreakpoint(final IRubyBreakpoint breakpoint) {
241+
LOGGER.fine("Disabling breakpoint: " + breakpoint);
242+
if (!isReady()) {
243+
LOGGER.fine("Session and/or debuggee is not ready, skipping addition of breakpoint: " + breakpoint);
244+
return;
245+
}
246+
try {
247+
if (breakpoint instanceof IRubyLineBreakpoint) {
248+
IRubyLineBreakpoint lineBreakpoint = (IRubyLineBreakpoint) breakpoint;
249+
Integer id = findBreakpointId(lineBreakpoint);
250+
String command = commandFactory.createDisableBreakpoint(id);
251+
if (command != null) {
252+
sendCommand(command);
253+
getReadersSupport().readDisabledBreakpointNo(id);
229254
} else {
230-
throw new IllegalArgumentException("Unknown breakpoint type: " + breakpoint);
255+
LOGGER.info("disabling breakpoints is nor supported by backend");
231256
}
232-
} catch (final RubyDebuggerException ex) {
233-
if (isReady()) {
234-
LOGGER.log(Level.WARNING, "Cannot add breakpoint to: " + getDebugTarget(), ex);
257+
} else {
258+
removeBreakpoint(breakpoint);
259+
}
260+
} catch (RubyDebuggerException e) {
261+
LOGGER.log(Level.SEVERE, "Exception during disabling breakpoint.", e);
262+
}
263+
}
264+
265+
private void enableBreakpoint(final IRubyBreakpoint breakpoint) {
266+
LOGGER.fine("Enabling breakpoint: " + breakpoint);
267+
if (!isReady()) {
268+
LOGGER.fine("Session and/or debuggee is not ready, skipping addition of breakpoint: " + breakpoint);
269+
return;
270+
}
271+
try {
272+
if (breakpoint instanceof IRubyLineBreakpoint) {
273+
IRubyLineBreakpoint lineBreakpoint = (IRubyLineBreakpoint) breakpoint;
274+
Integer id = findBreakpointId(lineBreakpoint);
275+
String command = commandFactory.createEnableBreakpoint(id);
276+
if (command != null) {
277+
sendCommand(command);
278+
getReadersSupport().readEnabledBreakpointNo(id);
279+
} else {
280+
LOGGER.info("disabling breakpoints is nor supported by backend");
235281
}
282+
} else {
283+
addBreakpoint(breakpoint);
236284
}
285+
} catch (RubyDebuggerException e) {
286+
LOGGER.log(Level.SEVERE, "Exception during enabling breakpoint.", e);
237287
}
238288
}
239-
289+
240290
public synchronized void removeBreakpoint(final IRubyBreakpoint breakpoint) {
241291
removeBreakpoint(breakpoint, false);
242292
}
@@ -285,21 +335,25 @@ public synchronized void removeBreakpoint(final IRubyBreakpoint breakpoint, bool
285335
/**
286336
* Update the given breakpoint. Use when <em>enabled</em> property has
287337
* changed.
338+
* @param breakpoint breakpoint to be updated
288339
*/
289-
public void updateBreakpoint(IRubyBreakpoint breakpoint) throws RubyDebuggerException {
290-
removeBreakpoint(breakpoint, true);
291-
addBreakpoint(breakpoint);
340+
public void updateBreakpoint(IRubyBreakpoint breakpoint) {
341+
if (breakpoint.isEnabled()) {
342+
enableBreakpoint(breakpoint);
343+
} else {
344+
disableBreakpoint(breakpoint);
345+
}
292346
}
293347

294348
/**
295349
* Find ID under which the given breakpoint is known in the current
296350
* debugging session.
297351
*
352+
* @param wantedBP breakpoint to search for
298353
* @return found ID; might be <tt>null</tt> if none is found
299354
*/
300355
private synchronized Integer findBreakpointId(final IRubyLineBreakpoint wantedBP) {
301-
for (Iterator<Map.Entry<Integer, IRubyLineBreakpoint>> it = breakpointsIDs.entrySet().iterator(); it.hasNext();) {
302-
Map.Entry<Integer, IRubyLineBreakpoint> breakpointID = it.next();
356+
for (Map.Entry<Integer, IRubyLineBreakpoint> breakpointID : breakpointsIDs.entrySet()) {
303357
IRubyLineBreakpoint bp = breakpointID.getValue();
304358
int id = breakpointID.getKey();
305359
if (wantedBP.getFilePath().equals(bp.getFilePath()) &&
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package org.rubyforge.debugcommons.reader;
2+
3+
import org.xmlpull.v1.XmlPullParser;
4+
import org.xmlpull.v1.XmlPullParserException;
5+
6+
import java.io.IOException;
7+
8+
public class BreakpointDisabledReader extends XmlStreamReader {
9+
10+
private int no;
11+
12+
public BreakpointDisabledReader(XmlPullParser xpp) {
13+
super(xpp);
14+
}
15+
16+
private void parse() throws XmlPullParserException, IOException {
17+
assert xpp.getName().equals("breakpointDisabled");
18+
no = getAttributeIntValue("bp_id");
19+
ensureEndTag("breakpointDisabled");
20+
}
21+
22+
public static int readBreakpointNo(final XmlPullParser xpp)
23+
throws IOException, XmlPullParserException {
24+
BreakpointDisabledReader reader = new BreakpointDisabledReader(xpp);
25+
reader.parse();
26+
return reader.no;
27+
}
28+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package org.rubyforge.debugcommons.reader;
2+
3+
import org.xmlpull.v1.XmlPullParser;
4+
import org.xmlpull.v1.XmlPullParserException;
5+
6+
import java.io.IOException;
7+
8+
public class BreakpointEnabledReader extends XmlStreamReader {
9+
10+
private int no;
11+
12+
public BreakpointEnabledReader(XmlPullParser xpp) {
13+
super(xpp);
14+
}
15+
16+
private void parse() throws XmlPullParserException, IOException {
17+
assert xpp.getName().equals("breakpointEnabled");
18+
no = getAttributeIntValue("bp_id");
19+
ensureEndTag("breakpointEnabled");
20+
}
21+
22+
public static int readBreakpointNo(final XmlPullParser xpp)
23+
throws IOException, XmlPullParserException {
24+
BreakpointEnabledReader reader = new BreakpointEnabledReader(xpp);
25+
reader.parse();
26+
return reader.no;
27+
}
28+
}

0 commit comments

Comments
 (0)