1 33 34 package edu.rice.cs.drjava.model.debug; 35 36 import edu.rice.cs.util.Log; 37 38 import com.sun.jdi.*; 39 import com.sun.jdi.event.*; 40 import com.sun.jdi.request.*; 41 import java.util.*; 42 import java.io.*; 43 44 47 public class EventHandlerThread extends Thread { 48 49 50 private final JPDADebugger _debugger; 51 52 53 private final VirtualMachine _vm; 54 55 56 private volatile boolean _connected; 57 58 59 private static final Log _log = new Log("EventTest", false); 60 61 66 EventHandlerThread(JPDADebugger debugger, VirtualMachine vm) { 67 super("DrJava Debug Event Handler"); 68 _debugger = debugger; 69 _vm = vm; 70 _connected = true; 71 } 72 73 76 private void _log(String message) { _log.log(message); } 77 78 82 private void _log(String message, Throwable t) { _log.log(message, t); } 83 84 85 public void run() { 86 _debugger.notifyDebuggerStarted(); 87 88 EventQueue queue = _vm.eventQueue(); 89 while (_connected) { 90 try { 91 try { 92 EventSet eventSet = queue.remove(); 94 EventIterator it = eventSet.eventIterator(); 95 96 while (it.hasNext()) handleEvent(it.nextEvent()); 97 } 98 catch (InterruptedException ie) { 99 _log("InterruptedException in main loop: " + ie); 102 } 103 catch (VMDisconnectedException de) { 104 handleDisconnectedException(); 106 break; 107 } 108 } 109 catch (Exception e) { 110 _log("Exception in main event handler loop.", e); 112 _debugger.eventHandlerError(e); 113 _debugger.printMessage("An exception occurred in the event handler:\n" + e); 114 _debugger.printMessage("The debugger may have become unstable as a result."); 115 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 116 e.printStackTrace(new PrintWriter(baos, true)); 117 _debugger.printMessage("Stack trace: "+baos.toString()); 118 } 119 } 120 121 _debugger.notifyDebuggerShutdown(); 122 } 123 124 127 private void handleEvent(Event e) throws DebugException { 128 _log("handling event: " + e); 130 131 if (e instanceof BreakpointEvent) _handleBreakpointEvent((BreakpointEvent) e); 132 else if (e instanceof StepEvent) _handleStepEvent((StepEvent) e); 133 else if (e instanceof ClassPrepareEvent) _handleClassPrepareEvent((ClassPrepareEvent) e); 137 else if (e instanceof ThreadStartEvent) _handleThreadStartEvent((ThreadStartEvent) e); 138 else if (e instanceof ThreadDeathEvent) _handleThreadDeathEvent((ThreadDeathEvent) e); 139 else if (e instanceof VMDeathEvent) _handleVMDeathEvent((VMDeathEvent) e); 140 else if (e instanceof VMDisconnectEvent) _handleVMDisconnectEvent((VMDisconnectEvent) e); 141 else 142 throw new DebugException("Unexpected event type: " + e); 143 } 144 145 146 private boolean _isSuspendedWithFrames(ThreadReference thread) throws DebugException { 147 148 try { return thread.isSuspended() && thread.frameCount() > 0; } 149 catch (IncompatibleThreadStateException itse) { 150 throw new DebugException("Could not count frames on a suspended thread: " + itse); 151 } 152 } 153 154 157 private void _handleBreakpointEvent(BreakpointEvent e) throws DebugException { 158 synchronized(_debugger) { 159 if (_isSuspendedWithFrames(e.thread()) && _debugger.setCurrentThread(e.thread())) { 160 _debugger.currThreadSuspended(); 162 _debugger.reachedBreakpoint((BreakpointRequest) e.request()); 164 } 165 } 166 } 167 168 171 private void _handleStepEvent(StepEvent e) throws DebugException { 172 synchronized(_debugger) { 173 if (_isSuspendedWithFrames(e.thread()) && _debugger.setCurrentThread(e.thread())) { 174 _debugger.printMessage("Stepped to " + e.location().declaringType().name() + "." + e.location().method().name() 175 + "(...) [line " + e.location().lineNumber() + "]"); 176 _debugger.currThreadSuspended(); 177 } 179 _debugger.getEventRequestManager().deleteEventRequest(e.request()); 181 } 182 } 183 184 194 199 private void _handleClassPrepareEvent(ClassPrepareEvent e) throws DebugException { 200 synchronized(_debugger) { 201 _debugger.getPendingRequestManager().classPrepared(e); 202 e.thread().resume(); 205 } 206 } 207 208 211 private void _handleThreadStartEvent(ThreadStartEvent e) { synchronized(_debugger) { _debugger.threadStarted(); } } 212 213 216 private void _handleThreadDeathEvent(ThreadDeathEvent e) throws DebugException { 217 synchronized(_debugger) { 220 ThreadReference running = _debugger.getCurrentRunningThread(); 221 if (e.thread().equals(running)) { 222 EventRequestManager erm = _vm.eventRequestManager(); 224 List steps = erm.stepRequests(); 225 for (int i = 0; i < steps.size(); i++) { 226 StepRequest step = (StepRequest)steps.get(i); 227 if (step.thread().equals(e.thread())) { 228 erm.deleteEventRequest(step); 229 230 break; 233 } 234 } 235 _debugger.currThreadDied(); 236 } 237 else _debugger.nonCurrThreadDied(); 238 } 239 240 e.thread().resume(); 242 } 243 244 247 private void _handleVMDeathEvent(VMDeathEvent e) throws DebugException { _cleanUp(e); } 248 249 253 private void _handleVMDisconnectEvent(VMDisconnectEvent e) throws DebugException { _cleanUp(e); } 254 255 258 private void _cleanUp(Event e) throws DebugException { 259 synchronized(_debugger) { 260 _connected = false; 261 if (_debugger.isReady()) { 262 _debugger.shutdown(); 265 } 266 } 267 } 268 269 271 private void handleDisconnectedException() throws DebugException { 272 EventQueue queue = _vm.eventQueue(); 273 while (_connected) { 274 try { 275 EventSet eventSet = queue.remove(); 276 EventIterator iter = eventSet.eventIterator(); 277 while (iter.hasNext()) { 278 Event event = iter.nextEvent(); 279 if (event instanceof VMDeathEvent) _handleVMDeathEvent((VMDeathEvent)event); 280 else if (event instanceof VMDisconnectEvent) _handleVMDisconnectEvent((VMDisconnectEvent)event); 281 } 283 eventSet.resume(); } 285 catch (InterruptedException ie) { 286 _log("InterruptedException after a disconnected exception.", ie); 288 } 289 catch (VMDisconnectedException de) { 290 _log("A second VMDisconnectedException.", de); 292 } 293 } 294 } 295 } 296 | Popular Tags |