1 /*
2 * Copyright (c) 1998, 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. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 #include <ctype.h>
27
28 #include "util.h"
29 #include "commonRef.h"
30 #include "debugDispatch.h"
31 #include "eventHandler.h"
32 #include "eventHelper.h"
33 #include "threadControl.h"
34 #include "stepControl.h"
35 #include "transport.h"
36 #include "classTrack.h"
37 #include "debugLoop.h"
38 #include "bag.h"
39 #include "invoker.h"
40 #include "sys.h"
41
42 /* How the options get to OnLoad: */
43 #define XDEBUG "-Xdebug"
44 #define XRUN "-Xrunjdwp"
45 #define AGENTLIB "-agentlib:jdwp"
46
47 /* Debug version defaults */
48 #ifdef DEBUG
49 #define DEFAULT_ASSERT_ON JNI_TRUE
50 #define DEFAULT_ASSERT_FATAL JNI_TRUE
51 #define DEFAULT_LOGFILE "jdwp.log"
52 #else
53 #define DEFAULT_ASSERT_ON JNI_FALSE
54 #define DEFAULT_ASSERT_FATAL JNI_FALSE
55 #define DEFAULT_LOGFILE NULL
56 #endif
57
58 static jboolean vmInitialized;
59 static jrawMonitorID initMonitor;
60 static jboolean initComplete;
61 static jbyte currentSessionID;
62
63 /*
64 * Options set through the OnLoad options string. All of these values
65 * are set once at VM startup and never reset.
66 */
67 static jboolean isServer = JNI_FALSE; /* Listens for connecting debuggers? */
68 static jboolean isStrict = JNI_FALSE; /* Unused */
69 static jboolean useStandardAlloc = JNI_FALSE; /* Use standard malloc/free? */
70 static struct bag *transports; /* of TransportSpec */
71
72 static jboolean initOnStartup = JNI_TRUE; /* init immediately */
73 static char *initOnException = NULL; /* init when this exception thrown */
74 static jboolean initOnUncaught = JNI_FALSE; /* init when uncaught exc thrown */
75
76 static char *launchOnInit = NULL; /* launch this app during init */
77 static jboolean suspendOnInit = JNI_TRUE; /* suspend all app threads after init */
78 static jboolean dopause = JNI_FALSE; /* pause for debugger attach */
79 static jboolean docoredump = JNI_FALSE; /* core dump on exit */
80 static char *logfile = NULL; /* Name of logfile (if logging) */
81 static unsigned logflags = 0; /* Log flags */
82
83 static char *names; /* strings derived from OnLoad options */
84
85 /*
86 * Elements of the transports bag
87 */
88 typedef struct TransportSpec {
89 char *name;
90 char *address;
91 long timeout;
92 } TransportSpec;
93
94 /*
95 * Forward Refs
96 */
97 static void JNICALL cbEarlyVMInit(jvmtiEnv*, JNIEnv *, jthread);
98 static void JNICALL cbEarlyVMDeath(jvmtiEnv*, JNIEnv *);
99 static void JNICALL cbEarlyException(jvmtiEnv*, JNIEnv *,
100 jthread, jmethodID, jlocation, jobject, jmethodID, jlocation);
101
102 static void initialize(JNIEnv *env, jthread thread, EventIndex triggering_ei);
103 static jboolean parseOptions(char *str);
104
105 /*
106 * Phase 1: Initial load.
107 *
108 * OnLoad is called by the VM immediately after the back-end
109 * library is loaded. We can do very little in this function since
110 * the VM has not completed initialization. So, we parse the JDWP
111 * options and set up a simple initial event callbacks for JVMTI events.
112 * When a triggering event occurs, that callback will begin debugger initialization.
113 */
114
115 /* Get a static area to hold the Global Data */
116 static BackendGlobalData *
get_gdata(void)117 get_gdata(void)
118 {
119 static BackendGlobalData s;
120 (void)memset(&s, 0, sizeof(BackendGlobalData));
121 return &s;
122 }
123
124 static jvmtiError
set_event_notification(jvmtiEventMode mode,EventIndex ei)125 set_event_notification(jvmtiEventMode mode, EventIndex ei)
126 {
127 jvmtiError error;
128 error = JVMTI_FUNC_PTR(gdata->jvmti,SetEventNotificationMode)
129 (gdata->jvmti, mode, eventIndex2jvmti(ei), NULL);
130 if (error != JVMTI_ERROR_NONE) {
131 ERROR_MESSAGE(("JDWP unable to configure initial JVMTI event %s: %s(%d)",
132 eventText(ei), jvmtiErrorText(error), error));
133 }
134 return error;
135 }
136
137 typedef struct {
138 int major;
139 int minor;
140 } version_type;
141
142 typedef struct {
143 version_type runtime;
144 version_type compiletime;
145 } compatible_versions_type;
146
147 /*
148 * List of explicitly compatible JVMTI versions, specified as
149 * { runtime version, compile-time version } pairs. -1 is a wildcard.
150 */
151 static int nof_compatible_versions = 3;
152 static compatible_versions_type compatible_versions_list[] = {
153 /*
154 * FIXUP: Allow version 0 to be compatible with anything
155 * Special check for FCS of 1.0.
156 */
157 { { 0, -1 }, { -1, -1 } },
158 { { -1, -1 }, { 0, -1 } },
159 /*
160 * 1.2 is runtime compatible with 1.1 -- just make sure to check the
161 * version before using any new 1.2 features
162 */
163 { { 1, 1 }, { 1, 2 } }
164 };
165
166
167 /* Logic to determine JVMTI version compatibility */
168 static jboolean
compatible_versions(jint major_runtime,jint minor_runtime,jint major_compiletime,jint minor_compiletime)169 compatible_versions(jint major_runtime, jint minor_runtime,
170 jint major_compiletime, jint minor_compiletime)
171 {
172 /*
173 * First check to see if versions are explicitly compatible via the
174 * list specified above.
175 */
176 int i;
177 for (i = 0; i < nof_compatible_versions; ++i) {
178 version_type runtime = compatible_versions_list[i].runtime;
179 version_type comptime = compatible_versions_list[i].compiletime;
180
181 if ((major_runtime == runtime.major || runtime.major == -1) &&
182 (minor_runtime == runtime.minor || runtime.minor == -1) &&
183 (major_compiletime == comptime.major || comptime.major == -1) &&
184 (minor_compiletime == comptime.minor || comptime.minor == -1)) {
185 return JNI_TRUE;
186 }
187 }
188
189 return major_runtime == major_compiletime &&
190 minor_runtime >= minor_compiletime;
191 }
192
193 /* OnLoad startup:
194 * Returning JNI_ERR will cause the java_g VM to core dump, be careful.
195 */
196 JNIEXPORT jint JNICALL
Agent_OnLoad(JavaVM * vm,char * options,void * reserved)197 Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
198 {
199 jvmtiError error;
200 jvmtiCapabilities needed_capabilities;
201 jvmtiCapabilities potential_capabilities;
202 jint jvmtiCompileTimeMajorVersion;
203 jint jvmtiCompileTimeMinorVersion;
204 jint jvmtiCompileTimeMicroVersion;
205 char *boot_path = NULL;
206 char npt_lib[MAXPATHLEN];
207
208 /* See if it's already loaded */
209 if ( gdata!=NULL && gdata->isLoaded==JNI_TRUE ) {
210 ERROR_MESSAGE(("Cannot load this JVM TI agent twice, check your java command line for duplicate jdwp options."));
211 return JNI_ERR;
212 }
213
214 /* If gdata is defined and the VM died, why are we here? */
215 if ( gdata!=NULL && gdata->vmDead ) {
216 ERROR_MESSAGE(("JDWP unable to load, VM died"));
217 return JNI_ERR;
218 }
219
220 /* Get global data area */
221 gdata = get_gdata();
222 if (gdata == NULL) {
223 ERROR_MESSAGE(("JDWP unable to allocate memory"));
224 return JNI_ERR;
225 }
226 gdata->isLoaded = JNI_TRUE;
227
228 /* Start filling in gdata */
229 gdata->jvm = vm;
230 vmInitialized = JNI_FALSE;
231 gdata->vmDead = JNI_FALSE;
232
233 /* Get the JVMTI Env, IMPORTANT: Do this first! For jvmtiAllocate(). */
234 error = JVM_FUNC_PTR(vm,GetEnv)
235 (vm, (void **)&(gdata->jvmti), JVMTI_VERSION_1);
236 if (error != JNI_OK) {
237 ERROR_MESSAGE(("JDWP unable to access JVMTI Version 1 (0x%x),"
238 " is your J2SE a 1.5 or newer version?"
239 " JNIEnv's GetEnv() returned %d",
240 JVMTI_VERSION_1, error));
241 forceExit(1); /* Kill entire process, no core dump */
242 }
243
244 /* Check to make sure the version of jvmti.h we compiled with
245 * matches the runtime version we are using.
246 */
247 jvmtiCompileTimeMajorVersion = ( JVMTI_VERSION & JVMTI_VERSION_MASK_MAJOR )
248 >> JVMTI_VERSION_SHIFT_MAJOR;
249 jvmtiCompileTimeMinorVersion = ( JVMTI_VERSION & JVMTI_VERSION_MASK_MINOR )
250 >> JVMTI_VERSION_SHIFT_MINOR;
251 jvmtiCompileTimeMicroVersion = ( JVMTI_VERSION & JVMTI_VERSION_MASK_MICRO )
252 >> JVMTI_VERSION_SHIFT_MICRO;
253
254 /* Check for compatibility */
255 if ( !compatible_versions(jvmtiMajorVersion(), jvmtiMinorVersion(),
256 jvmtiCompileTimeMajorVersion, jvmtiCompileTimeMinorVersion) ) {
257
258 ERROR_MESSAGE(("This jdwp native library will not work with this VM's "
259 "version of JVMTI (%d.%d.%d), it needs JVMTI %d.%d[.%d].",
260 jvmtiMajorVersion(),
261 jvmtiMinorVersion(),
262 jvmtiMicroVersion(),
263 jvmtiCompileTimeMajorVersion,
264 jvmtiCompileTimeMinorVersion,
265 jvmtiCompileTimeMicroVersion));
266
267 /* Do not let VM get a fatal error, we don't want a core dump here. */
268 forceExit(1); /* Kill entire process, no core dump wanted */
269 }
270
271 JVMTI_FUNC_PTR(gdata->jvmti, GetSystemProperty)
272 (gdata->jvmti, (const char *)"sun.boot.library.path",
273 &boot_path);
274
275 dbgsysBuildLibName(npt_lib, sizeof(npt_lib), boot_path, NPT_LIBNAME);
276 /* Npt and Utf function init */
277 NPT_INITIALIZE(npt_lib, &(gdata->npt), NPT_VERSION, NULL);
278 jvmtiDeallocate(boot_path);
279 if (gdata->npt == NULL) {
280 ERROR_MESSAGE(("JDWP: unable to initialize NPT library"));
281 return JNI_ERR;
282 }
283 gdata->npt->utf = (gdata->npt->utfInitialize)(NULL);
284 if (gdata->npt->utf == NULL) {
285 ERROR_MESSAGE(("JDWP: UTF function initialization failed"));
286 return JNI_ERR;
287 }
288
289 /* Parse input options */
290 if (!parseOptions(options)) {
291 /* No message necessary, should have been printed out already */
292 /* Do not let VM get a fatal error, we don't want a core dump here. */
293 forceExit(1); /* Kill entire process, no core dump wanted */
294 }
295
296 LOG_MISC(("Onload: %s", options));
297
298 /* Get potential capabilities */
299 (void)memset(&potential_capabilities,0,sizeof(potential_capabilities));
300 error = JVMTI_FUNC_PTR(gdata->jvmti,GetPotentialCapabilities)
301 (gdata->jvmti, &potential_capabilities);
302 if (error != JVMTI_ERROR_NONE) {
303 ERROR_MESSAGE(("JDWP unable to get potential JVMTI capabilities: %s(%d)",
304 jvmtiErrorText(error), error));
305 return JNI_ERR;
306 }
307
308 /* Fill in ones that we must have */
309 (void)memset(&needed_capabilities,0,sizeof(needed_capabilities));
310 needed_capabilities.can_access_local_variables = 1;
311 needed_capabilities.can_generate_single_step_events = 1;
312 needed_capabilities.can_generate_exception_events = 1;
313 needed_capabilities.can_generate_frame_pop_events = 1;
314 needed_capabilities.can_generate_breakpoint_events = 1;
315 needed_capabilities.can_suspend = 1;
316 needed_capabilities.can_generate_method_entry_events = 1;
317 needed_capabilities.can_generate_method_exit_events = 1;
318 needed_capabilities.can_generate_garbage_collection_events = 1;
319 needed_capabilities.can_maintain_original_method_order = 1;
320 needed_capabilities.can_generate_monitor_events = 1;
321 needed_capabilities.can_tag_objects = 1;
322
323 /* And what potential ones that would be nice to have */
324 needed_capabilities.can_force_early_return
325 = potential_capabilities.can_force_early_return;
326 needed_capabilities.can_generate_field_modification_events
327 = potential_capabilities.can_generate_field_modification_events;
328 needed_capabilities.can_generate_field_access_events
329 = potential_capabilities.can_generate_field_access_events;
330 needed_capabilities.can_get_bytecodes
331 = potential_capabilities.can_get_bytecodes;
332 needed_capabilities.can_get_synthetic_attribute
333 = potential_capabilities.can_get_synthetic_attribute;
334 needed_capabilities.can_get_owned_monitor_info
335 = potential_capabilities.can_get_owned_monitor_info;
336 needed_capabilities.can_get_current_contended_monitor
337 = potential_capabilities.can_get_current_contended_monitor;
338 needed_capabilities.can_get_monitor_info
339 = potential_capabilities.can_get_monitor_info;
340 needed_capabilities.can_pop_frame
341 = potential_capabilities.can_pop_frame;
342 needed_capabilities.can_redefine_classes
343 = potential_capabilities.can_redefine_classes;
344 needed_capabilities.can_redefine_any_class
345 = potential_capabilities.can_redefine_any_class;
346 needed_capabilities.can_get_owned_monitor_stack_depth_info
347 = potential_capabilities.can_get_owned_monitor_stack_depth_info;
348 needed_capabilities.can_get_constant_pool
349 = potential_capabilities.can_get_constant_pool;
350 {
351 needed_capabilities.can_get_source_debug_extension = 1;
352 needed_capabilities.can_get_source_file_name = 1;
353 needed_capabilities.can_get_line_numbers = 1;
354 needed_capabilities.can_signal_thread
355 = potential_capabilities.can_signal_thread;
356 }
357
358 /* Add the capabilities */
359 error = JVMTI_FUNC_PTR(gdata->jvmti,AddCapabilities)
360 (gdata->jvmti, &needed_capabilities);
361 if (error != JVMTI_ERROR_NONE) {
362 ERROR_MESSAGE(("JDWP unable to get necessary JVMTI capabilities."));
363 forceExit(1); /* Kill entire process, no core dump wanted */
364 }
365
366 /* Initialize event number mapping tables */
367 eventIndexInit();
368
369 /* Set the initial JVMTI event notifications */
370 error = set_event_notification(JVMTI_ENABLE, EI_VM_DEATH);
371 if (error != JVMTI_ERROR_NONE) {
372 return JNI_ERR;
373 }
374 error = set_event_notification(JVMTI_ENABLE, EI_VM_INIT);
375 if (error != JVMTI_ERROR_NONE) {
376 return JNI_ERR;
377 }
378 if (initOnUncaught || (initOnException != NULL)) {
379 error = set_event_notification(JVMTI_ENABLE, EI_EXCEPTION);
380 if (error != JVMTI_ERROR_NONE) {
381 return JNI_ERR;
382 }
383 }
384
385 /* Set callbacks just for 3 functions */
386 (void)memset(&(gdata->callbacks),0,sizeof(gdata->callbacks));
387 gdata->callbacks.VMInit = &cbEarlyVMInit;
388 gdata->callbacks.VMDeath = &cbEarlyVMDeath;
389 gdata->callbacks.Exception = &cbEarlyException;
390 error = JVMTI_FUNC_PTR(gdata->jvmti,SetEventCallbacks)
391 (gdata->jvmti, &(gdata->callbacks), sizeof(gdata->callbacks));
392 if (error != JVMTI_ERROR_NONE) {
393 ERROR_MESSAGE(("JDWP unable to set JVMTI event callbacks: %s(%d)",
394 jvmtiErrorText(error), error));
395 return JNI_ERR;
396 }
397
398 LOG_MISC(("OnLoad: DONE"));
399 return JNI_OK;
400 }
401
402 JNIEXPORT void JNICALL
Agent_OnUnload(JavaVM * vm)403 Agent_OnUnload(JavaVM *vm)
404 {
405
406 gdata->isLoaded = JNI_FALSE;
407
408 /* Cleanup, but make sure VM is alive before using JNI, and
409 * make sure JVMTI environment is ok before deallocating
410 * memory allocated through JVMTI, which all of it is.
411 */
412
413 /*
414 * Close transport before exit
415 */
416 if (transport_is_open()) {
417 transport_close();
418 }
419 }
420
421 /*
422 * Phase 2: Initial events. Phase 2 consists of waiting for the
423 * event that triggers full initialization. Under normal circumstances
424 * (initOnStartup == TRUE) this is the JVMTI_EVENT_VM_INIT event.
425 * Otherwise, we delay initialization until the app throws a
426 * particular exception. The triggering event invokes
427 * the bulk of the initialization, including creation of threads and
428 * monitors, transport setup, and installation of a new event callback which
429 * handles the complete set of events.
430 *
431 * Since the triggering event comes in on an application thread, some of the
432 * initialization is difficult to do here. Specifically, this thread along
433 * with all other app threads may need to be suspended until a debugger
434 * connects. These kinds of tasks are left to the third phase which is
435 * invoked by one of the spawned debugger threads, the event handler.
436 */
437
438 /*
439 * Wait for a triggering event; then kick off debugger
440 * initialization. A different event callback will be installed by
441 * debugger initialization, and this function will not be called
442 * again.
443 */
444
445 /*
446 * TO DO: Decide whether we need to protect this code with
447 * a lock. It might be too early to create a monitor safely (?).
448 */
449
450 static void JNICALL
cbEarlyVMInit(jvmtiEnv * jvmti_env,JNIEnv * env,jthread thread)451 cbEarlyVMInit(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread)
452 {
453 LOG_CB(("cbEarlyVMInit"));
454 if ( gdata->vmDead ) {
455 EXIT_ERROR(AGENT_ERROR_INTERNAL,"VM dead at VM_INIT time");
456 }
457 if (initOnStartup)
458 initialize(env, thread, EI_VM_INIT);
459 vmInitialized = JNI_TRUE;
460 LOG_MISC(("END cbEarlyVMInit"));
461 }
462
463 static void
disposeEnvironment(jvmtiEnv * jvmti_env)464 disposeEnvironment(jvmtiEnv *jvmti_env)
465 {
466 jvmtiError error;
467
468 error = JVMTI_FUNC_PTR(jvmti_env,DisposeEnvironment)(jvmti_env);
469 if ( error == JVMTI_ERROR_MUST_POSSESS_CAPABILITY )
470 error = JVMTI_ERROR_NONE; /* Hack! FIXUP when JVMTI has disposeEnv */
471 /* What should error return say? */
472 if (error != JVMTI_ERROR_NONE) {
473 ERROR_MESSAGE(("JDWP unable to dispose of JVMTI environment: %s(%d)",
474 jvmtiErrorText(error), error));
475 }
476 gdata->jvmti = NULL;
477 }
478
479 static void JNICALL
cbEarlyVMDeath(jvmtiEnv * jvmti_env,JNIEnv * env)480 cbEarlyVMDeath(jvmtiEnv *jvmti_env, JNIEnv *env)
481 {
482 LOG_CB(("cbEarlyVMDeath"));
483 if ( gdata->vmDead ) {
484 EXIT_ERROR(AGENT_ERROR_INTERNAL,"VM died more than once");
485 }
486 disposeEnvironment(jvmti_env);
487 gdata->jvmti = NULL;
488 gdata->jvm = NULL;
489 gdata->vmDead = JNI_TRUE;
490 LOG_MISC(("END cbEarlyVMDeath"));
491 }
492
493 static void JNICALL
cbEarlyException(jvmtiEnv * jvmti_env,JNIEnv * env,jthread thread,jmethodID method,jlocation location,jobject exception,jmethodID catch_method,jlocation catch_location)494 cbEarlyException(jvmtiEnv *jvmti_env, JNIEnv *env,
495 jthread thread, jmethodID method, jlocation location,
496 jobject exception,
497 jmethodID catch_method, jlocation catch_location)
498 {
499 jvmtiError error;
500 jthrowable currentException;
501
502 LOG_CB(("cbEarlyException: thread=%p", thread));
503
504 if ( gdata->vmDead ) {
505 EXIT_ERROR(AGENT_ERROR_INTERNAL,"VM dead at initial Exception event");
506 }
507 if (!vmInitialized) {
508 LOG_MISC(("VM is not initialized yet"));
509 return;
510 }
511
512 /*
513 * We want to preserve any current exception that might get wiped
514 * out during event handling (e.g. JNI calls). We have to rely on
515 * space for the local reference on the current frame because
516 * doing a PushLocalFrame here might itself generate an exception.
517 */
518
519 currentException = JNI_FUNC_PTR(env,ExceptionOccurred)(env);
520 JNI_FUNC_PTR(env,ExceptionClear)(env);
521
522 if (initOnUncaught && catch_method == NULL) {
523
524 LOG_MISC(("Initializing on uncaught exception"));
525 initialize(env, thread, EI_EXCEPTION);
526
527 } else if (initOnException != NULL) {
528
529 jclass clazz;
530
531 /* Get class of exception thrown */
532 clazz = JNI_FUNC_PTR(env,GetObjectClass)(env, exception);
533 if ( clazz != NULL ) {
534 char *signature = NULL;
535 /* initing on throw, check */
536 error = classSignature(clazz, &signature, NULL);
537 LOG_MISC(("Checking specific exception: looking for %s, got %s",
538 initOnException, signature));
539 if ( (error==JVMTI_ERROR_NONE) &&
540 (strcmp(signature, initOnException) == 0)) {
541 LOG_MISC(("Initializing on specific exception"));
542 initialize(env, thread, EI_EXCEPTION);
543 } else {
544 error = AGENT_ERROR_INTERNAL; /* Just to cause restore */
545 }
546 if ( signature != NULL ) {
547 jvmtiDeallocate(signature);
548 }
549 } else {
550 error = AGENT_ERROR_INTERNAL; /* Just to cause restore */
551 }
552
553 /* If initialize didn't happen, we need to restore things */
554 if ( error != JVMTI_ERROR_NONE ) {
555 /*
556 * Restore exception state from before callback call
557 */
558 LOG_MISC(("No initialization, didn't find right exception"));
559 if (currentException != NULL) {
560 JNI_FUNC_PTR(env,Throw)(env, currentException);
561 } else {
562 JNI_FUNC_PTR(env,ExceptionClear)(env);
563 }
564 }
565
566 }
567
568 LOG_MISC(("END cbEarlyException"));
569
570 }
571
572 typedef struct EnumerateArg {
573 jboolean isServer;
574 jdwpError error;
575 jint startCount;
576 } EnumerateArg;
577
578 static jboolean
startTransport(void * item,void * arg)579 startTransport(void *item, void *arg)
580 {
581 TransportSpec *transport = item;
582 EnumerateArg *enumArg = arg;
583 jdwpError serror;
584
585 LOG_MISC(("Begin startTransport"));
586 serror = transport_startTransport(enumArg->isServer, transport->name,
587 transport->address, transport->timeout);
588 if (serror != JDWP_ERROR(NONE)) {
589 ERROR_MESSAGE(("JDWP Transport %s failed to initialize, %s(%d)",
590 transport->name, jdwpErrorText(serror), serror));
591 enumArg->error = serror;
592 } else {
593 /* (Don't overwrite any previous error) */
594
595 enumArg->startCount++;
596 }
597
598 LOG_MISC(("End startTransport"));
599
600 return JNI_TRUE; /* Always continue, even if there was an error */
601 }
602
603 static void
signalInitComplete(void)604 signalInitComplete(void)
605 {
606 /*
607 * Initialization is complete
608 */
609 LOG_MISC(("signal initialization complete"));
610 debugMonitorEnter(initMonitor);
611 initComplete = JNI_TRUE;
612 debugMonitorNotifyAll(initMonitor);
613 debugMonitorExit(initMonitor);
614 }
615
616 /*
617 * Determine if initialization is complete.
618 */
619 jboolean
debugInit_isInitComplete(void)620 debugInit_isInitComplete(void)
621 {
622 return initComplete;
623 }
624
625 /*
626 * Wait for all initialization to complete.
627 */
628 void
debugInit_waitInitComplete(void)629 debugInit_waitInitComplete(void)
630 {
631 debugMonitorEnter(initMonitor);
632 while (!initComplete) {
633 debugMonitorWait(initMonitor);
634 }
635 debugMonitorExit(initMonitor);
636 }
637
638 /* All process exit() calls come from here */
639 void
forceExit(int exit_code)640 forceExit(int exit_code)
641 {
642 /* make sure the transport is closed down before we exit() */
643 transport_close();
644 exit(exit_code);
645 }
646
647 /* All JVM fatal error exits lead here (e.g. we need to kill the VM). */
648 static void
jniFatalError(JNIEnv * env,const char * msg,jvmtiError error,int exit_code)649 jniFatalError(JNIEnv *env, const char *msg, jvmtiError error, int exit_code)
650 {
651 JavaVM *vm;
652 char buf[512];
653
654 gdata->vmDead = JNI_TRUE;
655 if ( msg==NULL )
656 msg = "UNKNOWN REASON";
657 vm = gdata->jvm;
658 if ( env==NULL && vm!=NULL ) {
659 jint rc = (*((*vm)->GetEnv))(vm, (void **)&env, JNI_VERSION_1_2);
660 if (rc != JNI_OK ) {
661 env = NULL;
662 }
663 }
664 if ( error != JVMTI_ERROR_NONE ) {
665 (void)snprintf(buf, sizeof(buf), "JDWP %s, jvmtiError=%s(%d)",
666 msg, jvmtiErrorText(error), error);
667 } else {
668 (void)snprintf(buf, sizeof(buf), "JDWP %s", msg);
669 }
670 if (env != NULL) {
671 (*((*env)->FatalError))(env, buf);
672 } else {
673 /* Should rarely ever reach here, means VM is really dead */
674 print_message(stderr, "ERROR: JDWP: ", "\n",
675 "Can't call JNI FatalError(NULL, \"%s\")", buf);
676 }
677 forceExit(exit_code);
678 }
679
680 /*
681 * Initialize debugger back end modules
682 */
683 static void
initialize(JNIEnv * env,jthread thread,EventIndex triggering_ei)684 initialize(JNIEnv *env, jthread thread, EventIndex triggering_ei)
685 {
686 jvmtiError error;
687 EnumerateArg arg;
688 jbyte suspendPolicy;
689
690 LOG_MISC(("Begin initialize()"));
691 currentSessionID = 0;
692 initComplete = JNI_FALSE;
693
694 if ( gdata->vmDead ) {
695 EXIT_ERROR(AGENT_ERROR_INTERNAL,"VM dead at initialize() time");
696 }
697
698 /* Turn off the initial JVMTI event notifications */
699 error = set_event_notification(JVMTI_DISABLE, EI_EXCEPTION);
700 if (error != JVMTI_ERROR_NONE) {
701 EXIT_ERROR(error, "unable to disable JVMTI event notification");
702 }
703 error = set_event_notification(JVMTI_DISABLE, EI_VM_INIT);
704 if (error != JVMTI_ERROR_NONE) {
705 EXIT_ERROR(error, "unable to disable JVMTI event notification");
706 }
707 error = set_event_notification(JVMTI_DISABLE, EI_VM_DEATH);
708 if (error != JVMTI_ERROR_NONE) {
709 EXIT_ERROR(error, "unable to disable JVMTI event notification");
710 }
711
712 /* Remove initial event callbacks */
713 (void)memset(&(gdata->callbacks),0,sizeof(gdata->callbacks));
714 error = JVMTI_FUNC_PTR(gdata->jvmti,SetEventCallbacks)
715 (gdata->jvmti, &(gdata->callbacks), sizeof(gdata->callbacks));
716 if (error != JVMTI_ERROR_NONE) {
717 EXIT_ERROR(error, "unable to clear JVMTI callbacks");
718 }
719
720 commonRef_initialize();
721 util_initialize(env);
722 threadControl_initialize();
723 stepControl_initialize();
724 invoker_initialize();
725 debugDispatch_initialize();
726 classTrack_initialize(env);
727 debugLoop_initialize();
728
729 initMonitor = debugMonitorCreate("JDWP Initialization Monitor");
730
731
732 /*
733 * Initialize transports
734 */
735 arg.isServer = isServer;
736 arg.error = JDWP_ERROR(NONE);
737 arg.startCount = 0;
738
739 transport_initialize();
740 (void)bagEnumerateOver(transports, startTransport, &arg);
741
742 /*
743 * Exit with an error only if
744 * 1) none of the transports was successfully started, and
745 * 2) the application has not yet started running
746 */
747 if ((arg.error != JDWP_ERROR(NONE)) &&
748 (arg.startCount == 0) &&
749 initOnStartup) {
750 EXIT_ERROR(map2jvmtiError(arg.error), "No transports initialized");
751 }
752
753 eventHandler_initialize(currentSessionID);
754
755 signalInitComplete();
756
757 transport_waitForConnection();
758
759 suspendPolicy = suspendOnInit ? JDWP_SUSPEND_POLICY(ALL)
760 : JDWP_SUSPEND_POLICY(NONE);
761 if (triggering_ei == EI_VM_INIT) {
762 LOG_MISC(("triggering_ei == EI_VM_INIT"));
763 eventHelper_reportVMInit(env, currentSessionID, thread, suspendPolicy);
764 } else {
765 /*
766 * TO DO: Kludgy way of getting the triggering event to the
767 * just-attached debugger. It would be nice to make this a little
768 * cleaner. There is also a race condition where other events
769 * can get in the queue (from other not-yet-suspended threads)
770 * before this one does. (Also need to handle allocation error below?)
771 */
772 EventInfo info;
773 struct bag *initEventBag;
774 LOG_MISC(("triggering_ei != EI_VM_INIT"));
775 initEventBag = eventHelper_createEventBag();
776 (void)memset(&info,0,sizeof(info));
777 info.ei = triggering_ei;
778 eventHelper_recordEvent(&info, 0, suspendPolicy, initEventBag);
779 (void)eventHelper_reportEvents(currentSessionID, initEventBag);
780 bagDestroyBag(initEventBag);
781 }
782
783 if ( gdata->vmDead ) {
784 EXIT_ERROR(AGENT_ERROR_INTERNAL,"VM dead before initialize() completes");
785 }
786 LOG_MISC(("End initialize()"));
787 }
788
789 /*
790 * Restore all static data to the initialized state so that another
791 * debugger can connect properly later.
792 */
793 void
debugInit_reset(JNIEnv * env)794 debugInit_reset(JNIEnv *env)
795 {
796 EnumerateArg arg;
797
798 LOG_MISC(("debugInit_reset() beginning"));
799
800 currentSessionID++;
801 initComplete = JNI_FALSE;
802
803 eventHandler_reset(currentSessionID);
804 transport_reset();
805 debugDispatch_reset();
806 invoker_reset();
807 stepControl_reset();
808 threadControl_reset();
809 util_reset();
810 commonRef_reset(env);
811 classTrack_reset();
812
813 /*
814 * If this is a server, we are now ready to accept another connection.
815 * If it's a client, then we've cleaned up some (more should be added
816 * later) and we're done.
817 */
818 if (isServer) {
819 arg.isServer = JNI_TRUE;
820 arg.error = JDWP_ERROR(NONE);
821 arg.startCount = 0;
822 (void)bagEnumerateOver(transports, startTransport, &arg);
823
824 signalInitComplete();
825
826 transport_waitForConnection();
827 } else {
828 signalInitComplete(); /* Why? */
829 }
830
831 LOG_MISC(("debugInit_reset() completed."));
832 }
833
834
835 char *
debugInit_launchOnInit(void)836 debugInit_launchOnInit(void)
837 {
838 return launchOnInit;
839 }
840
841 jboolean
debugInit_suspendOnInit(void)842 debugInit_suspendOnInit(void)
843 {
844 return suspendOnInit;
845 }
846
847 /*
848 * code below is shamelessly swiped from hprof.
849 */
850
851 static int
get_tok(char ** src,char * buf,int buflen,char sep)852 get_tok(char **src, char *buf, int buflen, char sep)
853 {
854 int i;
855 char *p = *src;
856 for (i = 0; i < buflen; i++) {
857 if (p[i] == 0 || p[i] == sep) {
858 buf[i] = 0;
859 if (p[i] == sep) {
860 i++;
861 }
862 *src += i;
863 return i;
864 }
865 buf[i] = p[i];
866 }
867 /* overflow */
868 return 0;
869 }
870
871 static void
printUsage(void)872 printUsage(void)
873 {
874 TTY_MESSAGE((
875 " Java Debugger JDWP Agent Library\n"
876 " --------------------------------\n"
877 "\n"
878 " (see http://java.sun.com/products/jpda for more information)\n"
879 "\n"
880 "jdwp usage: java " AGENTLIB "=[help]|[<option>=<value>, ...]\n"
881 "\n"
882 "Option Name and Value Description Default\n"
883 "--------------------- ----------- -------\n"
884 "suspend=y|n wait on startup? y\n"
885 "transport=<name> transport spec none\n"
886 "address=<listen/attach address> transport spec \"\"\n"
887 "server=y|n listen for debugger? n\n"
888 "launch=<command line> run debugger on event none\n"
889 "onthrow=<exception name> debug on throw none\n"
890 "onuncaught=y|n debug on any uncaught? n\n"
891 "timeout=<timeout value> for listen/attach in milliseconds n\n"
892 "mutf8=y|n output modified utf-8 n\n"
893 "quiet=y|n control over terminal messages n\n"
894 "\n"
895 "Obsolete Options\n"
896 "----------------\n"
897 "strict=y|n\n"
898 "stdalloc=y|n\n"
899 "\n"
900 "Examples\n"
901 "--------\n"
902 " - Using sockets connect to a debugger at a specific address:\n"
903 " java " AGENTLIB "=transport=dt_socket,address=localhost:8000 ...\n"
904 " - Using sockets listen for a debugger to attach:\n"
905 " java " AGENTLIB "=transport=dt_socket,server=y,suspend=y ...\n"
906 "\n"
907 "Notes\n"
908 "-----\n"
909 " - A timeout value of 0 (the default) is no timeout.\n"
910 "\n"
911 "Warnings\n"
912 "--------\n"
913 " - The older " XRUN " interface can still be used, but will be removed in\n"
914 " a future release, for example:\n"
915 " java " XDEBUG " " XRUN ":[help]|[<option>=<value>, ...]\n"
916 ));
917
918 #ifdef DEBUG
919
920 TTY_MESSAGE((
921 "\n"
922 "Debugging Options Description Default\n"
923 "----------------- ----------- -------\n"
924 "pause=y|n pause to debug PID n\n"
925 "coredump=y|n coredump at exit n\n"
926 "errorexit=y|n exit on any error n\n"
927 "logfile=filename name of log file none\n"
928 "logflags=flags log flags (bitmask) none\n"
929 " JVM calls = 0x001\n"
930 " JNI calls = 0x002\n"
931 " JVMTI calls = 0x004\n"
932 " misc events = 0x008\n"
933 " step logs = 0x010\n"
934 " locations = 0x020\n"
935 " callbacks = 0x040\n"
936 " errors = 0x080\n"
937 " everything = 0xfff\n"
938 "debugflags=flags debug flags (bitmask) none\n"
939 " USE_ITERATE_THROUGH_HEAP 0x01\n"
940 "\n"
941 "Environment Variables\n"
942 "---------------------\n"
943 "_JAVA_JDWP_OPTIONS\n"
944 " Options can be added externally via this environment variable.\n"
945 " Anything contained in it will get a comma prepended to it (if needed),\n"
946 " then it will be added to the end of the options supplied via the\n"
947 " " XRUN " or " AGENTLIB " command line option.\n"
948 ));
949
950 #endif
951
952
953
954 }
955
checkAddress(void * bagItem,void * arg)956 static jboolean checkAddress(void *bagItem, void *arg)
957 {
958 TransportSpec *spec = (TransportSpec *)bagItem;
959 if (spec->address == NULL) {
960 ERROR_MESSAGE(("JDWP Non-server transport %s must have a connection "
961 "address specified through the 'address=' option",
962 spec->name));
963 return JNI_FALSE;
964 } else {
965 return JNI_TRUE;
966 }
967 }
968
969 static char *
add_to_options(char * options,char * new_options)970 add_to_options(char *options, char *new_options)
971 {
972 size_t originalLength;
973 char *combinedOptions;
974
975 /*
976 * Allocate enough space for both strings and
977 * comma in between.
978 */
979 originalLength = strlen(options);
980 combinedOptions = jvmtiAllocate((jint)originalLength + 1 +
981 (jint)strlen(new_options) + 1);
982 if (combinedOptions == NULL) {
983 return NULL;
984 }
985
986 (void)strcpy(combinedOptions, options);
987 (void)strcat(combinedOptions, ",");
988 (void)strcat(combinedOptions, new_options);
989
990 return combinedOptions;
991 }
992
993 static jboolean
get_boolean(char ** pstr,jboolean * answer)994 get_boolean(char **pstr, jboolean *answer)
995 {
996 char buf[80];
997 *answer = JNI_FALSE;
998 /*LINTED*/
999 if (get_tok(pstr, buf, (int)sizeof(buf), ',')) {
1000 if (strcmp(buf, "y") == 0) {
1001 *answer = JNI_TRUE;
1002 return JNI_TRUE;
1003 } else if (strcmp(buf, "n") == 0) {
1004 *answer = JNI_FALSE;
1005 return JNI_TRUE;
1006 }
1007 }
1008 return JNI_FALSE;
1009 }
1010
1011 /* atexit() callback */
1012 static void
atexit_finish_logging(void)1013 atexit_finish_logging(void)
1014 {
1015 /* Normal exit(0) (not _exit()) may only reach here */
1016 finish_logging(); /* Only first call matters */
1017 }
1018
1019 static jboolean
parseOptions(char * options)1020 parseOptions(char *options)
1021 {
1022 TransportSpec *currentTransport = NULL;
1023 char *end;
1024 char *current;
1025 int length;
1026 char *str;
1027 char *errmsg;
1028
1029 /* Set defaults */
1030 gdata->assertOn = DEFAULT_ASSERT_ON;
1031 gdata->assertFatal = DEFAULT_ASSERT_FATAL;
1032 logfile = DEFAULT_LOGFILE;
1033
1034 /* Options being NULL will end up being an error. */
1035 if (options == NULL) {
1036 options = "";
1037 }
1038
1039 /* Check for "help" BEFORE we add any environmental settings */
1040 if ((strcmp(options, "help")) == 0) {
1041 printUsage();
1042 forceExit(0); /* Kill entire process, no core dump wanted */
1043 }
1044
1045 /* These buffers are never freed */
1046 {
1047 char *envOptions;
1048
1049 /*
1050 * Add environmentally specified options.
1051 */
1052 envOptions = getenv("_JAVA_JDWP_OPTIONS");
1053 if (envOptions != NULL) {
1054 options = add_to_options(options, envOptions);
1055 if ( options==NULL ) {
1056 EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"options");
1057 }
1058 }
1059
1060 /*
1061 * Allocate a buffer for names derived from option strings. It should
1062 * never be longer than the original options string itself.
1063 * Also keep a copy of the options in gdata->options.
1064 */
1065 length = (int)strlen(options);
1066 gdata->options = jvmtiAllocate(length + 1);
1067 if (gdata->options == NULL) {
1068 EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"options");
1069 }
1070 (void)strcpy(gdata->options, options);
1071 names = jvmtiAllocate(length + 1);
1072 if (names == NULL) {
1073 EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"options");
1074 }
1075
1076 transports = bagCreateBag(sizeof(TransportSpec), 3);
1077 if (transports == NULL) {
1078 EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"transports");
1079 }
1080
1081 }
1082
1083 current = names;
1084 end = names + length;
1085 str = options;
1086
1087 while (*str) {
1088 char buf[100];
1089 /*LINTED*/
1090 if (!get_tok(&str, buf, (int)sizeof(buf), '=')) {
1091 goto syntax_error;
1092 }
1093 if (strcmp(buf, "transport") == 0) {
1094 currentTransport = bagAdd(transports);
1095 /*LINTED*/
1096 if (!get_tok(&str, current, (int)(end - current), ',')) {
1097 goto syntax_error;
1098 }
1099 currentTransport->name = current;
1100 current += strlen(current) + 1;
1101 } else if (strcmp(buf, "address") == 0) {
1102 if (currentTransport == NULL) {
1103 errmsg = "address specified without transport";
1104 goto bad_option_with_errmsg;
1105 }
1106 /*LINTED*/
1107 if (!get_tok(&str, current, (int)(end - current), ',')) {
1108 goto syntax_error;
1109 }
1110 currentTransport->address = current;
1111 current += strlen(current) + 1;
1112 } else if (strcmp(buf, "timeout") == 0) {
1113 if (currentTransport == NULL) {
1114 errmsg = "timeout specified without transport";
1115 goto bad_option_with_errmsg;
1116 }
1117 /*LINTED*/
1118 if (!get_tok(&str, current, (int)(end - current), ',')) {
1119 goto syntax_error;
1120 }
1121 currentTransport->timeout = atol(current);
1122 current += strlen(current) + 1;
1123 } else if (strcmp(buf, "launch") == 0) {
1124 /*LINTED*/
1125 if (!get_tok(&str, current, (int)(end - current), ',')) {
1126 goto syntax_error;
1127 }
1128 launchOnInit = current;
1129 current += strlen(current) + 1;
1130 } else if (strcmp(buf, "onthrow") == 0) {
1131 /* Read class name and convert in place to a signature */
1132 *current = 'L';
1133 /*LINTED*/
1134 if (!get_tok(&str, current + 1, (int)(end - current - 1), ',')) {
1135 goto syntax_error;
1136 }
1137 initOnException = current;
1138 while (*current != '\0') {
1139 if (*current == '.') {
1140 *current = '/';
1141 }
1142 current++;
1143 }
1144 *current++ = ';';
1145 *current++ = '\0';
1146 } else if (strcmp(buf, "assert") == 0) {
1147 /*LINTED*/
1148 if (!get_tok(&str, current, (int)(end - current), ',')) {
1149 goto syntax_error;
1150 }
1151 if (strcmp(current, "y") == 0) {
1152 gdata->assertOn = JNI_TRUE;
1153 gdata->assertFatal = JNI_FALSE;
1154 } else if (strcmp(current, "fatal") == 0) {
1155 gdata->assertOn = JNI_TRUE;
1156 gdata->assertFatal = JNI_TRUE;
1157 } else if (strcmp(current, "n") == 0) {
1158 gdata->assertOn = JNI_FALSE;
1159 gdata->assertFatal = JNI_FALSE;
1160 } else {
1161 goto syntax_error;
1162 }
1163 current += strlen(current) + 1;
1164 } else if (strcmp(buf, "pause") == 0) {
1165 if ( !get_boolean(&str, &dopause) ) {
1166 goto syntax_error;
1167 }
1168 if ( dopause ) {
1169 do_pause();
1170 }
1171 } else if (strcmp(buf, "coredump") == 0) {
1172 if ( !get_boolean(&str, &docoredump) ) {
1173 goto syntax_error;
1174 }
1175 } else if (strcmp(buf, "errorexit") == 0) {
1176 if ( !get_boolean(&str, &(gdata->doerrorexit)) ) {
1177 goto syntax_error;
1178 }
1179 } else if (strcmp(buf, "exitpause") == 0) {
1180 errmsg = "The exitpause option removed, use -XX:OnError";
1181 goto bad_option_with_errmsg;
1182 } else if (strcmp(buf, "precrash") == 0) {
1183 errmsg = "The precrash option removed, use -XX:OnError";
1184 goto bad_option_with_errmsg;
1185 } else if (strcmp(buf, "logfile") == 0) {
1186 /*LINTED*/
1187 if (!get_tok(&str, current, (int)(end - current), ',')) {
1188 goto syntax_error;
1189 }
1190 logfile = current;
1191 current += strlen(current) + 1;
1192 } else if (strcmp(buf, "logflags") == 0) {
1193 /*LINTED*/
1194 if (!get_tok(&str, current, (int)(end - current), ',')) {
1195 goto syntax_error;
1196 }
1197 /*LINTED*/
1198 logflags = (unsigned)strtol(current, NULL, 0);
1199 } else if (strcmp(buf, "debugflags") == 0) {
1200 /*LINTED*/
1201 if (!get_tok(&str, current, (int)(end - current), ',')) {
1202 goto syntax_error;
1203 }
1204 /*LINTED*/
1205 gdata->debugflags = (unsigned)strtol(current, NULL, 0);
1206 } else if ( strcmp(buf, "suspend")==0 ) {
1207 if ( !get_boolean(&str, &suspendOnInit) ) {
1208 goto syntax_error;
1209 }
1210 } else if ( strcmp(buf, "server")==0 ) {
1211 if ( !get_boolean(&str, &isServer) ) {
1212 goto syntax_error;
1213 }
1214 } else if ( strcmp(buf, "strict")==0 ) { /* Obsolete, but accept it */
1215 if ( !get_boolean(&str, &isStrict) ) {
1216 goto syntax_error;
1217 }
1218 } else if ( strcmp(buf, "quiet")==0 ) {
1219 if ( !get_boolean(&str, &(gdata->quiet)) ) {
1220 goto syntax_error;
1221 }
1222 } else if ( strcmp(buf, "onuncaught")==0 ) {
1223 if ( !get_boolean(&str, &initOnUncaught) ) {
1224 goto syntax_error;
1225 }
1226 } else if ( strcmp(buf, "mutf8")==0 ) {
1227 if ( !get_boolean(&str, &(gdata->modifiedUtf8)) ) {
1228 goto syntax_error;
1229 }
1230 } else if ( strcmp(buf, "stdalloc")==0 ) { /* Obsolete, but accept it */
1231 if ( !get_boolean(&str, &useStandardAlloc) ) {
1232 goto syntax_error;
1233 }
1234 } else {
1235 goto syntax_error;
1236 }
1237 }
1238
1239 /* Setup logging now */
1240 if ( logfile!=NULL ) {
1241 setup_logging(logfile, logflags);
1242 (void)atexit(&atexit_finish_logging);
1243 }
1244
1245 if (bagSize(transports) == 0) {
1246 errmsg = "no transport specified";
1247 goto bad_option_with_errmsg;
1248 }
1249
1250 /*
1251 * TO DO: Remove when multiple transports are allowed. (replace with
1252 * check below.
1253 */
1254 if (bagSize(transports) > 1) {
1255 errmsg = "multiple transports are not supported in this release";
1256 goto bad_option_with_errmsg;
1257 }
1258
1259
1260 if (!isServer) {
1261 jboolean specified = bagEnumerateOver(transports, checkAddress, NULL);
1262 if (!specified) {
1263 /* message already printed */
1264 goto bad_option_no_msg;
1265 }
1266 }
1267
1268 /*
1269 * The user has selected to wait for an exception before init happens
1270 */
1271 if ((initOnException != NULL) || (initOnUncaught)) {
1272 initOnStartup = JNI_FALSE;
1273
1274 if (launchOnInit == NULL) {
1275 /*
1276 * These rely on the launch=/usr/bin/foo
1277 * suboption, so it is an error if user did not
1278 * provide one.
1279 */
1280 errmsg = "Specify launch=<command line> when using onthrow or onuncaught suboption";
1281 goto bad_option_with_errmsg;
1282 }
1283 }
1284
1285 return JNI_TRUE;
1286
1287 syntax_error:
1288 ERROR_MESSAGE(("JDWP option syntax error: %s=%s", AGENTLIB, options));
1289 return JNI_FALSE;
1290
1291 bad_option_with_errmsg:
1292 ERROR_MESSAGE(("JDWP %s: %s=%s", errmsg, AGENTLIB, options));
1293 return JNI_FALSE;
1294
1295 bad_option_no_msg:
1296 ERROR_MESSAGE(("JDWP %s: %s=%s", "invalid option", AGENTLIB, options));
1297 return JNI_FALSE;
1298 }
1299
1300 /* All normal exit doors lead here */
1301 void
debugInit_exit(jvmtiError error,const char * msg)1302 debugInit_exit(jvmtiError error, const char *msg)
1303 {
1304 enum exit_codes { EXIT_NO_ERRORS = 0, EXIT_JVMTI_ERROR = 1, EXIT_TRANSPORT_ERROR = 2 };
1305
1306 // Prepare to exit. Log error and finish logging
1307 LOG_MISC(("Exiting with error %s(%d): %s", jvmtiErrorText(error), error,
1308 ((msg == NULL) ? "" : msg)));
1309
1310 // coredump requested by command line. Keep JVMTI data dirty
1311 if (error != JVMTI_ERROR_NONE && docoredump) {
1312 LOG_MISC(("Dumping core as requested by command line"));
1313 finish_logging();
1314 abort();
1315 }
1316
1317 finish_logging();
1318
1319 // Cleanup the JVMTI if we have one
1320 if (gdata != NULL) {
1321 gdata->vmDead = JNI_TRUE;
1322 if (gdata->jvmti != NULL) {
1323 // Dispose of jvmti (gdata->jvmti becomes NULL)
1324 disposeEnvironment(gdata->jvmti);
1325 }
1326 }
1327
1328 // We are here with no errors. Kill entire process and exit with zero exit code
1329 if (error == JVMTI_ERROR_NONE) {
1330 forceExit(EXIT_NO_ERRORS);
1331 return;
1332 }
1333
1334 // No transport initilized.
1335 // As we don't have any details here exiting with separate exit code
1336 if (error == AGENT_ERROR_TRANSPORT_INIT) {
1337 forceExit(EXIT_TRANSPORT_ERROR);
1338 return;
1339 }
1340
1341 // We have JVMTI error. Call hotspot jni_FatalError handler
1342 jniFatalError(NULL, msg, error, EXIT_JVMTI_ERROR);
1343
1344 // hotspot calls os:abort() so we should never reach code below,
1345 // but guard against possible hotspot changes
1346
1347 // Last chance to die, this kills the entire process.
1348 forceExit(EXIT_JVMTI_ERROR);
1349 }
1350