1 7 34 35 package com.sun.tools.example.trace; 36 37 import com.sun.jdi.*; 38 import com.sun.jdi.request.*; 39 import com.sun.jdi.event.*; 40 41 import java.util.*; 42 import java.io.PrintWriter ; 43 44 50 public class EventThread extends Thread { 51 52 private final VirtualMachine vm; private final String [] excludes; private final PrintWriter writer; 56 static String nextBaseIndent = ""; 58 private boolean connected = true; private boolean vmDied = true; 61 private Map traceMap = new HashMap(); 63 64 EventThread(VirtualMachine vm, String [] excludes, PrintWriter writer) { 65 super("event-handler"); 66 this.vm = vm; 67 this.excludes = excludes; 68 this.writer = writer; 69 } 70 71 76 public void run() { 77 EventQueue queue = vm.eventQueue(); 78 while (connected) { 79 try { 80 EventSet eventSet = queue.remove(); 81 EventIterator it = eventSet.eventIterator(); 82 while (it.hasNext()) { 83 handleEvent(it.nextEvent()); 84 } 85 eventSet.resume(); 86 } catch (InterruptedException exc) { 87 } catch (VMDisconnectedException discExc) { 89 handleDisconnectedException(); 90 break; 91 } 92 } 93 } 94 95 101 void setEventRequests(boolean watchFields) { 102 EventRequestManager mgr = vm.eventRequestManager(); 103 104 ExceptionRequest excReq = mgr.createExceptionRequest(null, 106 true, true); 107 excReq.setSuspendPolicy(EventRequest.SUSPEND_ALL); 109 excReq.enable(); 110 111 MethodEntryRequest menr = mgr.createMethodEntryRequest(); 112 for (int i=0; i<excludes.length; ++i) { 113 menr.addClassExclusionFilter(excludes[i]); 114 } 115 menr.setSuspendPolicy(EventRequest.SUSPEND_NONE); 116 menr.enable(); 117 118 MethodExitRequest mexr = mgr.createMethodExitRequest(); 119 for (int i=0; i<excludes.length; ++i) { 120 mexr.addClassExclusionFilter(excludes[i]); 121 } 122 mexr.setSuspendPolicy(EventRequest.SUSPEND_NONE); 123 mexr.enable(); 124 125 ThreadDeathRequest tdr = mgr.createThreadDeathRequest(); 126 tdr.setSuspendPolicy(EventRequest.SUSPEND_ALL); 128 tdr.enable(); 129 130 if (watchFields) { 131 ClassPrepareRequest cpr = mgr.createClassPrepareRequest(); 132 for (int i=0; i<excludes.length; ++i) { 133 cpr.addClassExclusionFilter(excludes[i]); 134 } 135 cpr.setSuspendPolicy(EventRequest.SUSPEND_ALL); 136 cpr.enable(); 137 } 138 } 139 140 144 class ThreadTrace { 145 final ThreadReference thread; 146 final String baseIndent; 147 static final String threadDelta = " "; 148 StringBuffer indent; 149 150 ThreadTrace(ThreadReference thread) { 151 this.thread = thread; 152 this.baseIndent = nextBaseIndent; 153 indent = new StringBuffer (baseIndent); 154 nextBaseIndent += threadDelta; 155 println("====== " + thread.name() + " ======"); 156 } 157 158 private void println(String str) { 159 writer.print(indent); 160 writer.println(str); 161 } 162 163 void methodEntryEvent(MethodEntryEvent event) { 164 println(event.method().name() + " -- " 165 + event.method().declaringType().name()); 166 indent.append("| "); 167 } 168 169 void methodExitEvent(MethodExitEvent event) { 170 indent.setLength(indent.length()-2); 171 } 172 173 void fieldWatchEvent(ModificationWatchpointEvent event) { 174 Field field = event.field(); 175 Value value = event.valueToBe(); 176 println(" " + field.name() + " = " + value); 177 } 178 179 void exceptionEvent(ExceptionEvent event) { 180 println("Exception: " + event.exception() + 181 " catch: " + event.catchLocation()); 182 183 EventRequestManager mgr = vm.eventRequestManager(); 185 StepRequest req = mgr.createStepRequest(thread, 186 StepRequest.STEP_MIN, 187 StepRequest.STEP_INTO); 188 req.addCountFilter(1); req.setSuspendPolicy(EventRequest.SUSPEND_ALL); 190 req.enable(); 191 } 192 193 void stepEvent(StepEvent event) { 195 int cnt = 0; 197 indent = new StringBuffer (baseIndent); 198 try { 199 cnt = thread.frameCount(); 200 } catch (IncompatibleThreadStateException exc) { 201 } 202 while (cnt-- > 0) { 203 indent.append("| "); 204 } 205 206 EventRequestManager mgr = vm.eventRequestManager(); 207 mgr.deleteEventRequest(event.request()); 208 } 209 210 void threadDeathEvent(ThreadDeathEvent event) { 211 indent = new StringBuffer (baseIndent); 212 println("====== " + thread.name() + " end ======"); 213 } 214 } 215 216 220 ThreadTrace threadTrace(ThreadReference thread) { 221 ThreadTrace trace = (ThreadTrace)traceMap.get(thread); 222 if (trace == null) { 223 trace = new ThreadTrace(thread); 224 traceMap.put(thread, trace); 225 } 226 return trace; 227 } 228 229 232 private void handleEvent(Event event) { 233 if (event instanceof ExceptionEvent) { 234 exceptionEvent((ExceptionEvent)event); 235 } else if (event instanceof ModificationWatchpointEvent) { 236 fieldWatchEvent((ModificationWatchpointEvent)event); 237 } else if (event instanceof MethodEntryEvent) { 238 methodEntryEvent((MethodEntryEvent)event); 239 } else if (event instanceof MethodExitEvent) { 240 methodExitEvent((MethodExitEvent)event); 241 } else if (event instanceof StepEvent) { 242 stepEvent((StepEvent)event); 243 } else if (event instanceof ThreadDeathEvent) { 244 threadDeathEvent((ThreadDeathEvent)event); 245 } else if (event instanceof ClassPrepareEvent) { 246 classPrepareEvent((ClassPrepareEvent)event); 247 } else if (event instanceof VMStartEvent) { 248 vmStartEvent((VMStartEvent)event); 249 } else if (event instanceof VMDeathEvent) { 250 vmDeathEvent((VMDeathEvent)event); 251 } else if (event instanceof VMDisconnectEvent) { 252 vmDisconnectEvent((VMDisconnectEvent)event); 253 } else { 254 throw new Error ("Unexpected event type"); 255 } 256 } 257 258 264 synchronized void handleDisconnectedException() { 265 EventQueue queue = vm.eventQueue(); 266 while (connected) { 267 try { 268 EventSet eventSet = queue.remove(); 269 EventIterator iter = eventSet.eventIterator(); 270 while (iter.hasNext()) { 271 Event event = iter.nextEvent(); 272 if (event instanceof VMDeathEvent) { 273 vmDeathEvent((VMDeathEvent)event); 274 } else if (event instanceof VMDisconnectEvent) { 275 vmDisconnectEvent((VMDisconnectEvent)event); 276 } 277 } 278 eventSet.resume(); } catch (InterruptedException exc) { 280 } 282 } 283 } 284 285 private void vmStartEvent(VMStartEvent event) { 286 writer.println("-- VM Started --"); 287 } 288 289 private void methodEntryEvent(MethodEntryEvent event) { 291 threadTrace(event.thread()).methodEntryEvent(event); 292 } 293 294 private void methodExitEvent(MethodExitEvent event) { 296 threadTrace(event.thread()).methodExitEvent(event); 297 } 298 299 private void stepEvent(StepEvent event) { 301 threadTrace(event.thread()).stepEvent(event); 302 } 303 304 private void fieldWatchEvent(ModificationWatchpointEvent event) { 306 threadTrace(event.thread()).fieldWatchEvent(event); 307 } 308 309 void threadDeathEvent(ThreadDeathEvent event) { 310 ThreadTrace trace = (ThreadTrace)traceMap.get(event.thread()); 311 if (trace != null) { trace.threadDeathEvent(event); } 314 } 315 316 320 private void classPrepareEvent(ClassPrepareEvent event) { 321 EventRequestManager mgr = vm.eventRequestManager(); 322 List fields = event.referenceType().visibleFields(); 323 for (Iterator it = fields.iterator(); it.hasNext(); ) { 324 Field field = (Field)it.next(); 325 ModificationWatchpointRequest req = 326 mgr.createModificationWatchpointRequest(field); 327 for (int i=0; i<excludes.length; ++i) { 328 req.addClassExclusionFilter(excludes[i]); 329 } 330 req.setSuspendPolicy(EventRequest.SUSPEND_NONE); 331 req.enable(); 332 } 333 } 334 335 private void exceptionEvent(ExceptionEvent event) { 336 ThreadTrace trace = (ThreadTrace)traceMap.get(event.thread()); 337 if (trace != null) { trace.exceptionEvent(event); } 340 } 341 342 public void vmDeathEvent(VMDeathEvent event) { 343 vmDied = true; 344 writer.println("-- The application exited --"); 345 } 346 347 public void vmDisconnectEvent(VMDisconnectEvent event) { 348 connected = false; 349 if (!vmDied) { 350 writer.println("-- The application has been disconnected --"); 351 } 352 } 353 } 354 | Popular Tags |