1 /* 2 * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 package nsk.jdi.ExceptionEvent.catchLocation; 25 26 import com.sun.jdi.*; 27 import com.sun.jdi.event.*; 28 import com.sun.jdi.request.*; 29 30 import java.io.*; 31 import java.util.Iterator; 32 import java.util.List; 33 34 import nsk.share.*; 35 import nsk.share.jpda.*; 36 import nsk.share.jdi.*; 37 38 39 // This class is the debugger in the test 40 41 public class location002 { 42 static final int PASSED = 0; 43 static final int FAILED = 2; 44 static final int JCK_STATUS_BASE = 95; 45 46 // time interval to wait for events 47 static final int TIMEOUT_DELTA = 1000; // milliseconds 48 49 // synchronization commands 50 static final String COMMAND_READY = "ready"; 51 static final String COMMAND_QUIT = "quit"; 52 static final String COMMAND_GO = "go"; 53 static final String COMMAND_DONE = "done"; 54 static final String COMMAND_ERROR = "error"; 55 56 // checked classes names 57 static final String DEBUGGEE_NAME = "nsk.jdi.ExceptionEvent.catchLocation.location002a"; 58 static final String JAVA_EXCEPTION = "java.lang.NumberFormatException"; 59 60 // scaffold objects 61 static private Debugee debuggee; 62 static private VirtualMachine vm; 63 static private IOPipe pipe; 64 static private Log log; 65 static private ArgumentHandler argHandler; 66 static private EventSet eventSet; 67 68 // timeout for waiting events 69 static private long eventTimeout; 70 71 // mirrors for checked classes and threads in debuggee 72 static private ExceptionRequest checkedRequest; 73 static private ReferenceType checkedClass; 74 static private ThreadReference checkedThread; 75 76 // results of test execution 77 static private boolean eventsReceived; 78 static private boolean testFailed; 79 80 // execute test from command line main(String args[])81 public static void main (String args[]) { 82 System.exit(run(args, System.out) + JCK_STATUS_BASE); 83 } 84 85 // execute test from JCK-compatible harness run(final String args[], final PrintStream out)86 public static int run(final String args[], final PrintStream out) { 87 88 testFailed = false; 89 90 argHandler = new ArgumentHandler(args); 91 log = new Log(out, argHandler); 92 eventTimeout = argHandler.getWaitTime() * 60 * 1000; // milliseconds 93 94 // launch debuggee 95 Binder binder = new Binder(argHandler, log); 96 log.display("Connecting to debuggee"); 97 debuggee = binder.bindToDebugee(DEBUGGEE_NAME); 98 debuggee.redirectStderr(log, "location001a >"); 99 100 // create synchronization channel with debuggee 101 pipe = debuggee.createIOPipe(); 102 vm = debuggee.VM(); 103 EventRequestManager erManager = vm.eventRequestManager(); 104 105 // resume debuggee 106 log.display("Resuming debuggee"); 107 debuggee.resume(); 108 109 // catch exceptions while testing and finally quit debuggee 110 try { 111 112 // wait for debuggee started 113 log.display("Waiting for command: " + COMMAND_READY); 114 String command = pipe.readln(); 115 if (!command.equals(COMMAND_READY)) { 116 throw new Failure("TEST BUG: unexpected debuggee's command: " + command); 117 } 118 119 // get mirrors of checked classes in debuggee 120 log.display("Getting loaded classes in debuggee"); 121 if ((checkedClass = debuggee.classByName(DEBUGGEE_NAME)) == null) { 122 throw new Failure("TEST BUG: cannot find " + DEBUGGEE_NAME); 123 } 124 125 // get mirror of main thread in debuggee 126 log.display("Getting reference to main thread"); 127 Iterator threadIterator = vm.allThreads().iterator(); 128 while (threadIterator.hasNext()) { 129 ThreadReference curThread = (ThreadReference) threadIterator.next(); 130 if (curThread.name().equals("main")) { 131 checkedThread = curThread; 132 } 133 } 134 if (checkedThread == null) { 135 throw new Failure("TEST BUG: unable to find reference to main thread"); 136 } 137 138 // create ExceptionRequest for all throwable classes (initially disabled) 139 log.display("Creating ExceptionRequest"); 140 boolean notifyCaught = true; 141 boolean notifyUncaught = true; 142 if ((checkedRequest = erManager.createExceptionRequest(null, notifyCaught, notifyUncaught)) == null) { 143 throw new Failure("TEST BUG: unable to create ExceptionRequest"); 144 } 145 146 // define separate thread for handling received events 147 class EventHandler extends Thread { 148 public void run() { 149 // handle events until expected event received 150 eventHandlingLoop: 151 while (!eventsReceived) { 152 eventSet = null; 153 try { 154 eventSet = vm.eventQueue().remove(TIMEOUT_DELTA); 155 } catch (InterruptedException e) { 156 log.complain("Unexpected InterruptedException while receiving event: " + e); 157 break; 158 } 159 160 if (eventSet == null) { 161 continue; 162 } 163 164 // handle each event from event set 165 EventIterator eventIterator = eventSet.eventIterator(); 166 while (eventIterator.hasNext()) { 167 168 Event event = eventIterator.nextEvent(); 169 // log.display("Event received:\n " + event); 170 171 // break event handling loop if VMDisconnectEvent received 172 if (event instanceof VMDisconnectEvent) { 173 log.display("VMDisconnectEvent received"); 174 break eventHandlingLoop; 175 } 176 177 // handle ExceptionEvent 178 if (event instanceof ExceptionEvent) { 179 log.display("ExceptionEvent received"); 180 181 ExceptionEvent castedEvent = (ExceptionEvent)event; 182 ReferenceType eventRefType = castedEvent.exception().referenceType(); 183 184 String eventTypeName = eventRefType.name(); 185 if (eventTypeName.equals(JAVA_EXCEPTION)) { 186 log.display("Expected ExceptionEvent for " + JAVA_EXCEPTION + " is received"); 187 eventsReceived = true; 188 189 Location catchLocation = castedEvent.catchLocation(); 190 if (catchLocation != null) { 191 log.complain("FAILURE 1: catchLocation for uncaught " + JAVA_EXCEPTION + 192 " is not null :"); 193 log.complain("declaring type: " + catchLocation.declaringType().name()); 194 log.complain("line number : " + catchLocation.lineNumber()); 195 } 196 197 } 198 } 199 200 // ignore each other events 201 202 } // end of event handling loop 203 204 // log.display("Resuming event set"); 205 eventSet.resume(); 206 207 } // end of event set handling loop 208 209 log.display("eventHandler completed"); 210 211 } // end of run() 212 213 } // end of EventHandler 214 215 // start EventHandler thread 216 EventHandler eventHandler = new EventHandler(); 217 log.display("Starting eventHandler"); 218 eventHandler.start(); 219 220 // enable event request 221 log.display("Enabling ExceptionRequest"); 222 checkedRequest.enable(); 223 224 // force debuggee to throw exceptions and generate events 225 log.display("Sending command: " + COMMAND_GO); 226 pipe.println(COMMAND_GO); 227 228 // wait for all expected events received or timeout exceeds 229 log.display("Waiting for all expected events received"); 230 try { 231 eventHandler.join(eventTimeout); 232 if (eventHandler.isAlive()) { 233 log.complain("FAILURE 20: Timeout for waiting event was exceeded"); 234 eventHandler.interrupt(); 235 testFailed = true; 236 } 237 } catch (InterruptedException e) { 238 log.complain("TEST INCOMPLETE: InterruptedException caught while waiting for eventHandler's death"); 239 testFailed = true; 240 } 241 242 // complain if not all expected events received 243 if (!eventsReceived) { 244 log.complain("FAILURE 2: " + JAVA_EXCEPTION + " was not received"); 245 testFailed= true; 246 } 247 248 // end testing 249 250 } catch (Failure e) { 251 log.complain("TEST FAILURE: " + e.getMessage()); 252 testFailed = true; 253 } catch (Exception e) { 254 log.complain("Unexpected exception: " + e); 255 e.printStackTrace(out); 256 testFailed = true; 257 } finally { 258 259 log.display(""); 260 261 // wait for debuggee exits and analize its exit code 262 log.display("Waiting for debuggee terminating"); 263 int debuggeeStatus = debuggee.endDebugee(); 264 log.display("Debuggee terminated with exit code: " + debuggeeStatus); 265 } 266 267 // check test results 268 if (testFailed) { 269 log.complain("TEST FAILED"); 270 return FAILED; 271 } 272 273 log.display("TEST PASSED"); 274 return PASSED; 275 } 276 } 277