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