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