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