alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (standardHandlers.c)

This example Java source code file (standardHandlers.c) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

ei_breakpoint, ei_class_prepare, ei_exception, ei_monitor_contended_entered, ei_monitor_waited, ei_single_step, ei_thread_end, ei_vm_death, eventinfo, framenumber, handlernode, jdwp_suspend_policy, jvmti_func_ptr, null

The standardHandlers.c Java example source code

/*
 * Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
/*
 * handlers
 *
 * The default event request handler functions
 */

#include "util.h"
#include "eventHandler.h"
#include "threadControl.h"
#include "eventHelper.h"
#include "classTrack.h"

#include "standardHandlers.h"

static void
handleClassPrepare(JNIEnv *env, EventInfo *evinfo,
                   HandlerNode *node,
                   struct bag *eventBag)
{
    jthread thread = evinfo->thread;

    /* We try hard to avoid class loads/prepares in debugger
     * threads, but it is still possible for them to happen (most
     * likely for exceptions that are thrown within JNI
     * methods). If such an event occurs, we must report it, but
     * we cannot suspend the debugger thread.
     *
     * 1) We report the thread as NULL because we don't want the
     *    application to get hold of a debugger thread object.
     * 2) We try to do the right thing wrt to suspending
     *    threads without suspending debugger threads. If the
     *    requested suspend policy is NONE, there's no problem. If
     *    the requested policy is ALL, we can just suspend all
     *    application threads without producing any surprising
     *    results by leaving the debugger thread running. However,
     *    if the requested policy is EVENT_THREAD, we are forced
     *    to do something different than requested. The most
     *    useful behavior is to suspend all application threads
     *    (just as if the policy was ALL). This allows the
     *    application to operate on the class before it gets into
     *    circulation and so it is preferable to the other
     *    alternative of suspending no threads.
     */
    if (threadControl_isDebugThread(thread)) {
        evinfo->thread = NULL;
        if (node->suspendPolicy == JDWP_SUSPEND_POLICY(EVENT_THREAD)) {
            node->suspendPolicy = JDWP_SUSPEND_POLICY(ALL);
        }
    }
    eventHelper_recordEvent(evinfo, node->handlerID,
                            node->suspendPolicy, eventBag);
}

static void
handleGarbageCollectionFinish(JNIEnv *env, EventInfo *evinfo,
                  HandlerNode *node,
                  struct bag *eventBag)
{
    JDI_ASSERT_MSG(JNI_FALSE, "Should never call handleGarbageCollectionFinish");
}

static void
handleFrameEvent(JNIEnv *env, EventInfo *evinfo,
                 HandlerNode *node,
                 struct bag *eventBag)
{
    /*
     * The frame id that comes with this event is very transient.
     * We can't send the frame to the helper thread because it
     * might be useless by the time the helper thread can use it
     * (if suspend policy is NONE). So, get the needed info from
     * the frame and then use a special command to the helper
     * thread.
     */

    jmethodID method;
    jlocation location;
    jvmtiError error;
    FrameNumber fnum = 0;
    jvalue returnValue;

    error = JVMTI_FUNC_PTR(gdata->jvmti,GetFrameLocation)
            (gdata->jvmti, evinfo->thread, fnum, &method, &location);
    if (error != JVMTI_ERROR_NONE) {
        location = -1;
    }
    returnValue = evinfo->u.method_exit.return_value;

    eventHelper_recordFrameEvent(node->handlerID,
                                 node->suspendPolicy,
                                 evinfo->ei,
                                 evinfo->thread,
                                 evinfo->clazz,
                                 evinfo->method,
                                 location,
                                 node->needReturnValue,
                                 returnValue,
                                 eventBag);
}

static void
genericHandler(JNIEnv *env, EventInfo *evinfo,
               HandlerNode *node,
               struct bag *eventBag)
{
    eventHelper_recordEvent(evinfo, node->handlerID, node->suspendPolicy,
                            eventBag);
}

HandlerFunction
standardHandlers_defaultHandler(EventIndex ei)
{
    switch (ei) {
        case EI_BREAKPOINT:
        case EI_EXCEPTION:
        case EI_FIELD_ACCESS:
        case EI_FIELD_MODIFICATION:
        case EI_SINGLE_STEP:
        case EI_THREAD_START:
        case EI_THREAD_END:
        case EI_VM_DEATH:
        case EI_MONITOR_CONTENDED_ENTER:
        case EI_MONITOR_CONTENDED_ENTERED:
        case EI_MONITOR_WAIT:
        case EI_MONITOR_WAITED:
            return &genericHandler;

        case EI_CLASS_PREPARE:
            return &handleClassPrepare;

        case EI_GC_FINISH:
            return &handleGarbageCollectionFinish;

        case EI_METHOD_ENTRY:
        case EI_METHOD_EXIT:
            return &handleFrameEvent;

        default:
            /* This NULL will trigger a AGENT_ERROR_INVALID_EVENT_TYPE */
            return NULL;
    }
}

void
standardHandlers_onConnect(void)
{
    jboolean installed;

    /* always report VMDeath to a connected debugger */
    installed = (eventHandler_createPermanentInternal(
                        EI_VM_DEATH, genericHandler) != NULL);
    if (!installed) {
        EXIT_ERROR(AGENT_ERROR_INVALID_EVENT_TYPE,"Unable to install VM Death event handler");
    }
}

void
standardHandlers_onDisconnect(void)
{
}

Other Java examples (source code examples)

Here is a short list of links related to this Java standardHandlers.c source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.