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