Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/Java/Openjdk/src/jdk.jdwp.agent/share/native/libjdwp/   (Sun/Oracle ©)  Datei vom 13.11.2022 mit Größe 5 kB image not shown  

Quelle  classTrack.c   Sprache: C

 
/*
 * Copyright (c) 2001, 2022, 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.
 */


/*
 * This module tracks classes that have been prepared, so as to
 * be able to report which have been unloaded. On VM start-up
 * and whenever new classes are loaded, all prepared classes'
 * signatures are attached as JVMTI tag to the class object.
 * Class unloading is tracked by registering
 * ObjectFree callback on class objects. When this happens, we find
 * the signature of the unloaded class(es) and report them back
 * to the event handler to synthesize class-unload-events.
 */


#include "util.h"
#include "bag.h"
#include "classTrack.h"
#include "eventHandler.h"

#define NOT_TAGGED 0

/*
 * The JVMTI tracking env to keep track of klass tags for class-unloads
 */

static jvmtiEnv* trackingEnv;

static void addPreparedClass(JNIEnv *env, jclass klass);

/*
 * Invoke the callback when classes are freed.
 */

void JNICALL
cbTrackingObjectFree(jvmtiEnv* jvmti_env, jlong tag)
{
    JDI_ASSERT(jvmti_env == trackingEnv);
    eventHandler_synthesizeUnloadEvent((char*)jlong_to_ptr(tag), getEnv());
}

/*
 * Invoke the callback when classes are prepared.
 */

void JNICALL
cbTrackingClassPrepare(jvmtiEnv* jvmti_env, JNIEnv *env, jthread thread, jclass klass)
{
    JDI_ASSERT(jvmti_env == trackingEnv);
    addPreparedClass(env, klass);
}

/*
 * It's ok to get WRONG_PHASE errors once the vm is dead. We can just
 * ignore the event in that case.
 */

static jboolean
is_wrong_phase(jvmtiError error)
{
    if (error == JVMTI_ERROR_WRONG_PHASE) {
        JDI_ASSERT(gdata->vmDead);
        return JNI_TRUE;
    }
    return JNI_FALSE;
}


/*
 * Add a class to the prepared class hash table.
 */

static void
addPreparedClass(JNIEnv *env, jclass klass)
{
    jvmtiError error;

    char* signature;
    error = classSignature(klass, &signature, NULL);
    if (is_wrong_phase(error)) {
        return;
    }
    if (error != JVMTI_ERROR_NONE) {
        EXIT_ERROR(error,"signature");
    }

    if (gdata->assertOn) {
        // Check if already tagged.
        jlong tag;
        error = JVMTI_FUNC_PTR(trackingEnv, GetTag)(trackingEnv, klass, &tag);
        if (is_wrong_phase(error)) {
            return;
        }
        if (error != JVMTI_ERROR_NONE) {
            EXIT_ERROR(error, "Unable to GetTag with class trackingEnv");
        }
        if (tag != NOT_TAGGED) {
            // If tagged, the old tag better be the same as the new.
            char* oldSignature = (char*)jlong_to_ptr(tag);
            JDI_ASSERT(strcmp(signature, oldSignature) == 0);
            jvmtiDeallocate(signature);
            return;
        }
    }

    error = JVMTI_FUNC_PTR(trackingEnv, SetTag)(trackingEnv, klass, ptr_to_jlong(signature));
    if (is_wrong_phase(error)) {
        return;
    }
    if (error != JVMTI_ERROR_NONE) {
        jvmtiDeallocate(signature);
        EXIT_ERROR(error,"SetTag");
    }
}

static jboolean
setupEvents()
{
    jvmtiCapabilities caps;
    memset(&caps, 0, sizeof(caps));
    caps.can_generate_object_free_events = 1;
    jvmtiError error = JVMTI_FUNC_PTR(trackingEnv, AddCapabilities)(trackingEnv, &caps);
    if (error != JVMTI_ERROR_NONE) {
        return JNI_FALSE;
    }
    jvmtiEventCallbacks cb;
    memset(&cb, 0, sizeof(cb));

    // Setup JVMTI callbacks
    cb.ObjectFree = cbTrackingObjectFree;
    cb.ClassPrepare = cbTrackingClassPrepare;
    error = JVMTI_FUNC_PTR(trackingEnv, SetEventCallbacks)(trackingEnv, &cb, sizeof(cb));
    if (error != JVMTI_ERROR_NONE) {
        return JNI_FALSE;
    }

    // Enable OBJECT_FREE events
    error = JVMTI_FUNC_PTR(trackingEnv, SetEventNotificationMode)(trackingEnv, JVMTI_ENABLE, JVMTI_EVENT_OBJECT_FREE, NULL);
    if (error != JVMTI_ERROR_NONE) {
        return JNI_FALSE;
    }

    // Enable CLASS_PREPARE events
    error = JVMTI_FUNC_PTR(trackingEnv, SetEventNotificationMode)(trackingEnv, JVMTI_ENABLE, JVMTI_EVENT_CLASS_PREPARE, NULL);
    if (error != JVMTI_ERROR_NONE) {
        return JNI_FALSE;
    }

    return JNI_TRUE;
}

/*
 * Called once to initialize class-tracking.
 */

void
classTrack_initialize(JNIEnv *env)
{
    trackingEnv = getSpecialJvmti();
    if (trackingEnv == NULL) {
        EXIT_ERROR(AGENT_ERROR_INTERNAL, "Failed to allocate tag-tracking jvmtiEnv");
    }


    if (!setupEvents()) {
        EXIT_ERROR(AGENT_ERROR_INTERNAL, "Unable to setup ObjectFree tracking");
    }

    jint classCount;
    jclass *classes;
    jvmtiError error;
    jint i;

    error = allLoadedClasses(&classes, &classCount);
    if ( error == JVMTI_ERROR_NONE ) {
        for (i = 0; i < classCount; i++) {
            jclass klass = classes[i];
            jint status;
            jint wanted = JVMTI_CLASS_STATUS_PREPARED | JVMTI_CLASS_STATUS_ARRAY;
            status = classStatus(klass);
            if ((status & wanted) != 0) {
                addPreparedClass(env, klass);
            }
        }
        jvmtiDeallocate(classes);
    } else {
        EXIT_ERROR(error,"loaded classes array");
    }
}

92%


¤ Dauer der Verarbeitung: 0.1 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.