1 /******************************************************************************* 2 * Copyright (c) 2000, 2013 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 *******************************************************************************/ 14 package org.eclipse.debug.core; 15 16 17 import java.util.EventObject; 18 19 import org.eclipse.debug.internal.core.DebugCoreMessages; 20 21 /** 22 * A debug event describes an event in a program being debugged or in a running 23 * process. Debug models and process implementations are required to generate 24 * debug events as specified by this class. 25 * <p> 26 * The following list defines the events generated for each debug model element. 27 * The <code>getSource()</code> method of a debug event returns the element 28 * associated with the event. Creation events are guaranteed to occur in a top 29 * down order - that is, parents are created before children. Termination events 30 * are guaranteed to occur in a bottom up order - that is, children before 31 * parents. However, termination events are not guaranteed for all elements that 32 * are created. That is, terminate events can be coalesced - a terminate event 33 * for a parent signals that all children have been terminated. 34 * </p> 35 * <p> 36 * A debug model may define model specific events by specifying a debug event 37 * kind of <code>MODEL_SPECIFIC</code>. A model specific event is identified by 38 * the event source (i.e. by the debug model that generated the event). The 39 * detail of a model specific event is client defined. Note that model specific 40 * events are not understood by the debug platform, and are thus ignored. 41 * </p> 42 * <p> 43 * The generic <code>CHANGE</code> event can be fired at any time by any 44 * element. Generally, a client of a debug model, such as as a UI, can get 45 * sufficient information to update by listening/responding to the other event 46 * kinds. However, if a debug model needs to inform clients of a change that is 47 * not specified by create/terminate/suspend/resume, the <code>CHANGE</code> 48 * event may be used. For example, generally, the only way a thread or any of 49 * its children can change state between a suspend and resume operation, is if 50 * the thread or owning debug target is terminated. However, if a debug model 51 * supports some other operation that would allow a debug element to change 52 * state while suspended, the debug model would fire a change event for that 53 * element. The valid detail codes for a change event are: 54 * </p> 55 * <ul> 56 * <li><code>STATE</code> - indicates the state of an element has changed, but 57 * its children are not affected. A client would use a state change event to 58 * update a label of the affected element, but would not update any 59 * children.</li> 60 * <li><code>CONTENT</code> - indicates that a debug element's value or contents 61 * have changed in some way. For example, when the value of a variable is 62 * changed explicitly, the variable should fire a content change event.</li> 63 * </ul> 64 * 65 * <ul> 66 * <li><code>IProcess</code> 67 * <ul> 68 * <li><code>CREATE</code> - a process has been created and is executing.</li> 69 * <li><code>TERMINATE</code> - a process has terminated.</li> 70 * </ul> 71 * <li><code>IDebugTarget</code> 72 * <ul> 73 * <li><code>CREATE</code> - a debug target has been created and is ready to 74 * begin a debug session.</li> 75 * <li><code>TERMINATE</code> - a debug target has terminated and the debug 76 * session has ended.</li> 77 * <li><code>SUSPEND</code> - a debug target has suspended. Event detail 78 * provides the reason for the suspension: 79 * <ul> 80 * <li><code>STEP_END</code> - a request to step has completed</li> 81 * <li><code>BREAKPOINT</code> - a breakpoint has been hit</li> 82 * <li><code>CLIENT_REQUEST</code> - a client request has caused the target to 83 * suspend (i.e. an explicit call to <code>suspend()</code>)</li> 84 * <li><code>UNSPECIFIED</code> - the reason for the suspend is not 85 * specified</li> 86 * </ul> 87 * </li> 88 * <li><code>RESUME</code> - a debug target has resumed. Event detail provides 89 * the reason for the resume: 90 * <ul> 91 * <li><code>STEP_INTO</code> - a target is being resumed because of a request 92 * to step into</li> 93 * <li><code>STEP_OVER</code> - a target is being resumed because of a request 94 * to step over</li> 95 * <li><code>STEP_RETURN</code> - a target is being resumed because of a request 96 * to step return</li> 97 * <li><code>CLIENT_REQUEST</code> - a client request has caused the target to 98 * be resumed (i.e. an explicit call to <code>resume()</code>)</li> 99 * <li><code>UNSPECIFIED</code> - The reason for the resume is not 100 * specified</li> 101 * </ul> 102 * </li> 103 * </ul> 104 * </li> 105 * <li><code>IThread</code> 106 * <ul> 107 * <li><code>CREATE</code> - a thread has been created in a debug target.</li> 108 * <li><code>TERMINATE</code> - a thread has terminated.</li> 109 * <li><code>SUSPEND</code> - a thread has suspended execution. Event detail 110 * provides the reason for the suspension: 111 * <ul> 112 * <li><code>STEP_END</code> - a request to step has completed</li> 113 * <li><code>BREAKPOINT</code> - a breakpoint has been hit</li> 114 * <li><code>CLIENT_REQUEST</code> - a client request has caused the thread to 115 * suspend (i.e. an explicit call to <code>suspend()</code>)</li> 116 * <li><code>EVALUATION</code> - an expression evaluation has ended that may 117 * have had side effects in the debug target.</li> 118 * <li><code>EVALUATION_IMPLICIT</code> - an expression evaluation has ended 119 * that had no side effects in the debug target.</li> 120 * <li><code>UNSPECIFIED</code> - the reason for the suspend is not 121 * specified</li> 122 * </ul> 123 * </li> 124 * <li><code>RESUME</code> - a thread has resumed execution. Event detail 125 * provides the reason for the resume: 126 * <ul> 127 * <li><code>STEP_INTO</code> - a thread is being resumed because of a request 128 * to step into</li> 129 * <li><code>STEP_OVER</code> - a thread is being resumed because of a request 130 * to step over</li> 131 * <li><code>STEP_RETURN</code> - a thread is being resumed because of a request 132 * to step return</li> 133 * <li><code>CLIENT_REQUEST</code> - a client request has caused the thread to 134 * be resumed (i.e. an explicit call to <code>resume()</code>)</li> 135 * <li><code>EVALUATION</code> - an expression evaluation has started that may 136 * have side effects in the debug target.</li> 137 * <li><code>EVALUATION_IMPLICIT</code> - an expression evaluation has started 138 * that will have no side effects in the debug target.</li> 139 * <li><code>UNSPECIFIED</code> - The reason for the resume is not 140 * specified</li> 141 * </ul> 142 * </li> 143 * </ul> 144 * </li> 145 * <li><code>IStackFrame</code> - no events are specified for stack frames. When 146 * a thread is suspended, it has stack frames. When a thread resumes, stack 147 * frames are unavailable.</li> 148 * <li><code>IVariable</code> - no events are specified for variables. When a 149 * thread is suspended, stack frames have variables. When a thread resumes, 150 * variables are unavailable.</li> 151 * <li><code>IValue</code> - no events are specified for values.</li> 152 * </ul> 153 * 154 */ 155 public final class DebugEvent extends EventObject { 156 157 /** 158 * All objects that can be serialized should have a stable serialVersionUID 159 */ 160 private static final long serialVersionUID = 1L; 161 162 /** 163 * Resume event kind. 164 */ 165 public static final int RESUME= 0x0001; 166 167 /** 168 * Suspend event kind. 169 */ 170 public static final int SUSPEND= 0x0002; 171 172 /** 173 * Create event kind. 174 */ 175 public static final int CREATE= 0x0004; 176 177 /** 178 * Terminate event kind. 179 */ 180 public static final int TERMINATE= 0x0008; 181 182 /** 183 * Change event kind. 184 */ 185 public static final int CHANGE= 0x0010; 186 187 /** 188 * Model specific event kind. The detail codes 189 * for a model specific event are client defined. 190 * 191 * @since 2.1.2 192 */ 193 public static final int MODEL_SPECIFIC= 0x0020; 194 195 /** 196 * Step start detail. Indicates a thread was resumed by a step 197 * into action. 198 * @since 2.0 199 */ 200 public static final int STEP_INTO= 0x0001; 201 202 /** 203 * Step start detail. Indicates a thread was resumed by a step 204 * over action. 205 * @since 2.0 206 */ 207 public static final int STEP_OVER= 0x0002; 208 209 /** 210 * Step start detail. Indicates a thread was resumed by a step 211 * return action. 212 * @since 2.0 213 */ 214 public static final int STEP_RETURN= 0x0004; 215 216 /** 217 * Step end detail. Indicates a thread was suspended due 218 * to the completion of a step action. 219 */ 220 public static final int STEP_END= 0x0008; 221 222 /** 223 * Breakpoint detail. Indicates a thread was suspended by 224 * a breakpoint. 225 */ 226 public static final int BREAKPOINT= 0x0010; 227 228 /** 229 * Client request detail. Indicates a thread was suspended due 230 * to a client request. 231 */ 232 public static final int CLIENT_REQUEST= 0x0020; 233 234 /** 235 * Evaluation detail. Indicates that a thread was resumed or 236 * suspended to perform an expression evaluation. 237 * 238 * @since 2.0 239 */ 240 public static final int EVALUATION = 0x0040; 241 242 /** 243 * Evaluation detail. Indicates that a thread was resumed or 244 * suspended to perform an implicit expression evaluation. 245 * An implicit evaluation is an evaluation that is performed 246 * as an indirect result of a user action. 247 * Clients may use this detail event to decide whether or not 248 * to alert the user that an evaluation is taking place.. 249 * 250 * @since 2.0 251 */ 252 public static final int EVALUATION_IMPLICIT = 0x0080; 253 254 /** 255 * State change detail. Indicates the state of a single 256 * debug element has changed. Only valid for <code>CHANGE</code> 257 * events. 258 * 259 * @since 2.0 260 */ 261 public static final int STATE = 0x0100; 262 263 /** 264 * Content change detail. Indicates the content of a debug element 265 * (and potentially its children) has changed. Only valid for 266 * <code>CHANGE</code> events. 267 * 268 * @since 2.0 269 */ 270 public static final int CONTENT = 0x0200; 271 272 /** 273 * Constant indicating that the kind or detail of a debug 274 * event is unspecified. 275 */ 276 public static final int UNSPECIFIED = 0; 277 278 /** 279 * The kind of event - one of the kind constants defined by 280 * this class. 281 */ 282 private int fKind= UNSPECIFIED; 283 284 /** 285 * The detail of the event - one of the detail constants defined by 286 * this class. 287 */ 288 private int fDetail= UNSPECIFIED; 289 290 /** 291 * Client defined data field. 292 * 293 * @since 2.1.2 294 */ 295 private Object fData = null; 296 297 /** 298 * Constructs a new debug event of the given kind with a detail code of 299 * <code>UNSPECIFIED</code>. 300 * 301 * @param eventSource the object associated with the event 302 * @param kind the kind of debug event (one of the 303 * kind constants defined by this class) 304 */ DebugEvent(Object eventSource, int kind)305 public DebugEvent(Object eventSource, int kind) { 306 this(eventSource, kind, UNSPECIFIED); 307 } 308 309 /** 310 * Constructs a new debug event of the given kind with the given detail. 311 * 312 * @param eventSource the object associated with the event 313 * @param kind the kind of debug event (one of the 314 * kind constants defined by this class) 315 * @param detail extra information about the event (one of the 316 * detail constants defined by this class or a client defined detail if this is a model specific event) 317 */ DebugEvent(Object eventSource, int kind, int detail)318 public DebugEvent(Object eventSource, int kind, int detail) { 319 super(eventSource); 320 if ((kind & (RESUME | SUSPEND | CREATE | TERMINATE | CHANGE | MODEL_SPECIFIC)) == 0) { 321 throw new IllegalArgumentException(DebugCoreMessages.DebugEvent_illegal_kind); 322 } 323 if (kind != MODEL_SPECIFIC && detail != UNSPECIFIED && (detail & (STEP_END | STEP_INTO | STEP_OVER | STEP_RETURN | BREAKPOINT | CLIENT_REQUEST |EVALUATION | EVALUATION_IMPLICIT | STATE | CONTENT)) == 0) { 324 throw new IllegalArgumentException(DebugCoreMessages.DebugEvent_illegal_detail); 325 } 326 fKind= kind; 327 fDetail= detail; 328 } 329 330 /** 331 * Returns a constant describing extra detail about the event - either one 332 * of the detail constants defined by this class, possibly 333 * <code>UNSPECIFIED</code>, or a client defined detail if this is a model specific event. 334 * 335 * @return the detail code 336 */ getDetail()337 public int getDetail() { 338 return fDetail; 339 } 340 341 /** 342 * Returns this event's kind - one of the kind constants defined by this class. 343 * 344 * @return the kind code 345 */ getKind()346 public int getKind() { 347 return fKind; 348 } 349 350 /** 351 * Returns whether this event's detail indicates the 352 * beginning of a step event. This event's detail is one 353 * of <code>STEP_INTO</code>, <code>STEP_OVER</code>, or 354 * <code>STEP_RETURN</code>. 355 * 356 * @return whether this event's detail indicates the beginning 357 * of a step event. 358 * @since 2.0 359 */ isStepStart()360 public boolean isStepStart() { 361 return (getDetail() & (STEP_INTO | STEP_OVER | STEP_RETURN)) > 0; 362 } 363 364 /** 365 * Returns whether this event's detail indicates an 366 * evaluation. This event's detail is one 367 * of <code>EVALUATION</code>, or <code>EVALUATION_IMPLICIT</code>. 368 * 369 * @return whether this event's detail indicates an evaluation. 370 * @since 2.0 371 */ isEvaluation()372 public boolean isEvaluation() { 373 return (getDetail() & (EVALUATION | EVALUATION_IMPLICIT)) > 0; 374 } 375 376 /** 377 * Sets this event's application defined data. 378 * 379 * @param data application defined data 380 * @since 2.1.2 381 */ setData(Object data)382 public void setData(Object data) { 383 fData = data; 384 } 385 386 /** 387 * Returns this event's application defined data, or <code>null</code> if none 388 * 389 * @return application defined data, or <code>null</code> if none 390 * @since 2.1.2 391 */ getData()392 public Object getData() { 393 return fData; 394 } 395 396 /** 397 * @see java.lang.Object#toString() 398 */ 399 @Override toString()400 public String toString() { 401 StringBuilder buf = new StringBuilder("DebugEvent["); //$NON-NLS-1$ 402 if (getSource() != null) { 403 buf.append(getSource().toString()); 404 } else { 405 buf.append("null"); //$NON-NLS-1$ 406 } 407 buf.append(", "); //$NON-NLS-1$ 408 switch (getKind()) { 409 case CREATE: 410 buf.append("CREATE"); //$NON-NLS-1$ 411 break; 412 case TERMINATE: 413 buf.append("TERMINATE"); //$NON-NLS-1$ 414 break; 415 case RESUME: 416 buf.append("RESUME"); //$NON-NLS-1$ 417 break; 418 case SUSPEND: 419 buf.append("SUSPEND"); //$NON-NLS-1$ 420 break; 421 case CHANGE: 422 buf.append("CHANGE"); //$NON-NLS-1$ 423 break; 424 case UNSPECIFIED: 425 buf.append("UNSPECIFIED"); //$NON-NLS-1$ 426 break; 427 case MODEL_SPECIFIC: 428 buf.append("MODEL_SPECIFIC"); //$NON-NLS-1$ 429 break; 430 default: 431 break; 432 } 433 buf.append(", "); //$NON-NLS-1$ 434 switch (getDetail()) { 435 case BREAKPOINT: 436 buf.append("BREAKPOINT"); //$NON-NLS-1$ 437 break; 438 case CLIENT_REQUEST: 439 buf.append("CLIENT_REQUEST"); //$NON-NLS-1$ 440 break; 441 case STEP_END: 442 buf.append("STEP_END"); //$NON-NLS-1$ 443 break; 444 case STEP_INTO: 445 buf.append("STEP_INTO"); //$NON-NLS-1$ 446 break; 447 case STEP_OVER: 448 buf.append("STEP_OVER"); //$NON-NLS-1$ 449 break; 450 case STEP_RETURN: 451 buf.append("STEP_RETURN"); //$NON-NLS-1$ 452 break; 453 case EVALUATION: 454 buf.append("EVALUATION"); //$NON-NLS-1$ 455 break; 456 case EVALUATION_IMPLICIT: 457 buf.append("EVALUATION_IMPLICIT"); //$NON-NLS-1$ 458 break; 459 case STATE: 460 buf.append("STATE"); //$NON-NLS-1$ 461 break; 462 case CONTENT: 463 buf.append("CONTENT"); //$NON-NLS-1$ 464 break; 465 case UNSPECIFIED: 466 buf.append("UNSPECIFIED"); //$NON-NLS-1$ 467 break; 468 default: 469 // model specific 470 buf.append(getDetail()); 471 break; 472 } 473 buf.append("]"); //$NON-NLS-1$ 474 return buf.toString(); 475 } 476 } 477 478