8331896: JFR: Improve check for JDK classes
Reviewed-by: mgronlun
This commit is contained in:
parent
3cbdf8d4d4
commit
8e903eeb1f
@ -28,6 +28,7 @@ import java.lang.reflect.Modifier;
|
||||
|
||||
import jdk.jfr.internal.event.EventConfiguration;
|
||||
import jdk.jfr.internal.util.Bytecode;
|
||||
import jdk.jfr.internal.util.Utils;
|
||||
/**
|
||||
* All upcalls from the JVM should go through this class.
|
||||
*
|
||||
@ -59,7 +60,7 @@ final class JVMUpcalls {
|
||||
static byte[] onRetransform(long traceId, boolean dummy1, boolean dummy2, Class<?> clazz, byte[] oldBytes) throws Throwable {
|
||||
try {
|
||||
if (jdk.internal.event.Event.class.isAssignableFrom(clazz) && !Modifier.isAbstract(clazz.getModifiers())) {
|
||||
if (!JVMSupport.shouldInstrument(clazz.getClassLoader() == null, clazz.getName())) {
|
||||
if (!JVMSupport.shouldInstrument(Utils.isJDKClass(clazz), clazz.getName())) {
|
||||
Logger.log(LogTag.JFR_SYSTEM, LogLevel.INFO, "Skipping instrumentation for " + clazz.getName() + " since container support is missing");
|
||||
return oldBytes;
|
||||
}
|
||||
@ -70,9 +71,9 @@ final class JVMUpcalls {
|
||||
// Probably triggered by some other agent
|
||||
return oldBytes;
|
||||
}
|
||||
boolean bootClassLoader = clazz.getClassLoader() == null;
|
||||
boolean jdkClass = Utils.isJDKClass(clazz);
|
||||
Logger.log(LogTag.JFR_SYSTEM, LogLevel.INFO, "Adding instrumentation to event class " + clazz.getName() + " using retransform");
|
||||
EventInstrumentation ei = new EventInstrumentation(clazz.getSuperclass(), oldBytes, traceId, bootClassLoader, false);
|
||||
EventInstrumentation ei = new EventInstrumentation(clazz.getSuperclass(), oldBytes, traceId, jdkClass, false);
|
||||
byte[] bytes = ei.buildInstrumented();
|
||||
Bytecode.log(clazz.getName(), bytes);
|
||||
return bytes;
|
||||
|
@ -204,7 +204,7 @@ public final class MetadataRepository {
|
||||
// and assign the result to a long field is not enough to always get a proper
|
||||
// stack trace. Purpose of the mechanism is to transfer metadata, such as
|
||||
// native type IDs, without specialized Java logic for each type.
|
||||
if (eventClass.getClassLoader() == null) {
|
||||
if (Utils.isJDKClass(eventClass)) {
|
||||
Name name = eventClass.getAnnotation(Name.class);
|
||||
if (name != null) {
|
||||
String n = name.value();
|
||||
|
@ -48,6 +48,7 @@ import jdk.jfr.events.VirtualThreadStartEvent;
|
||||
import jdk.jfr.events.VirtualThreadSubmitFailedEvent;
|
||||
import jdk.jfr.events.X509CertificateEvent;
|
||||
import jdk.jfr.events.X509ValidationEvent;
|
||||
import jdk.jfr.internal.util.Utils;
|
||||
|
||||
/**
|
||||
* This class registers all mirror events.
|
||||
@ -85,7 +86,7 @@ final class MirrorEvents {
|
||||
}
|
||||
|
||||
static Class<? extends MirrorEvent> find(Class<? extends jdk.internal.event.Event> eventClass) {
|
||||
return find(eventClass.getClassLoader() == null, eventClass.getName());
|
||||
return find(Utils.isJDKClass(eventClass), eventClass.getName());
|
||||
}
|
||||
|
||||
static Class<? extends MirrorEvent> find(boolean bootClassLoader, String name) {
|
||||
|
@ -166,7 +166,9 @@ public final class TypeLibrary {
|
||||
for (ValueDescriptor v : type.getFields()) {
|
||||
values.add(invokeAnnotation(annotation, v.getName()));
|
||||
}
|
||||
return PrivateAccess.getInstance().newAnnotation(type, values, annotation.annotationType().getClassLoader() == null);
|
||||
// Only annotation classes in the boot class loader can always be resolved.
|
||||
boolean bootClassLoader = annotationType.getClassLoader() == null;
|
||||
return PrivateAccess.getInstance().newAnnotation(type, values, bootClassLoader);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -220,7 +222,7 @@ public final class TypeLibrary {
|
||||
long id = Type.getTypeId(clazz);
|
||||
Type t;
|
||||
if (eventType) {
|
||||
t = new PlatformEventType(typeName, id, clazz.getClassLoader() == null, true);
|
||||
t = new PlatformEventType(typeName, id, Utils.isJDKClass(clazz), true);
|
||||
} else {
|
||||
t = new Type(typeName, superType, id);
|
||||
}
|
||||
@ -283,7 +285,7 @@ public final class TypeLibrary {
|
||||
}
|
||||
addAnnotations(clazz, type, dynamicAnnotations);
|
||||
|
||||
if (clazz.getClassLoader() == null) {
|
||||
if (Utils.isJDKClass(clazz)) {
|
||||
type.log("Added", LogTag.JFR_SYSTEM_METADATA, LogLevel.INFO);
|
||||
} else {
|
||||
type.log("Added", LogTag.JFR_METADATA, LogLevel.INFO);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, 2024, 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
|
||||
@ -25,6 +25,7 @@
|
||||
package jdk.jfr.internal.periodic;
|
||||
|
||||
import jdk.internal.event.Event;
|
||||
import jdk.jfr.internal.util.Utils;
|
||||
|
||||
/**
|
||||
* Periodic task that runs trusted code that doesn't require an access control
|
||||
@ -39,11 +40,11 @@ final class JDKEventTask extends JavaEventTask {
|
||||
if (!getEventType().isJDK()) {
|
||||
throw new InternalError("Must be a JDK event");
|
||||
}
|
||||
if (eventClass.getClassLoader() != null) {
|
||||
throw new SecurityException("Periodic task can only be registered for event classes that are loaded by the bootstrap class loader");
|
||||
if (!Utils.isJDKClass(eventClass)) {
|
||||
throw new SecurityException("Periodic task can only be registered for event classes that belongs to the JDK");
|
||||
}
|
||||
if (runnable.getClass().getClassLoader() != null) {
|
||||
throw new SecurityException("Runnable class must be loaded by the bootstrap class loader");
|
||||
if (!Utils.isJDKClass(runnable.getClass())) {
|
||||
throw new SecurityException("Runnable class must belong to the JDK");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -435,4 +435,12 @@ public final class Utils {
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static boolean isJDKClass(Class<?> type) {
|
||||
return type.getClassLoader() == null;
|
||||
// In the future we might want to also do:
|
||||
// type.getClassLoader() == ClassLoader.getPlatformClassLoader();
|
||||
// but only if it is safe and there is a mechanism to register event
|
||||
// classes in other modules besides jdk.jfr and java.base.
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user