8261160: Add a deserialization JFR event

Co-authored-by: Sean Coffey <coffeys@openjdk.org>
Co-authored-by: Chris Hegarty <chegar@openjdk.org>
Reviewed-by: coffeys, rriggs, dfuchs, egahlin
This commit is contained in:
Chris Hegarty 2021-02-12 17:35:25 +00:00
parent a305743cfa
commit 3dc6f52a89
12 changed files with 615 additions and 22 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2021, 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
@ -48,6 +48,7 @@ import java.util.concurrent.ConcurrentMap;
import static java.io.ObjectStreamClass.processQueue;
import jdk.internal.access.SharedSecrets;
import jdk.internal.event.DeserializationEvent;
import jdk.internal.misc.Unsafe;
import sun.reflect.misc.ReflectUtil;
import sun.security.action.GetBooleanAction;
@ -1323,9 +1324,12 @@ public class ObjectInputStream
}
/**
* Invoke the serialization filter if non-null.
* Invokes the serialization filter if non-null.
*
* If the filter rejects or an exception is thrown, throws InvalidClassException.
*
* Logs and/or commits a {@code DeserializationEvent}, if configured.
*
* @param clazz the class; may be null
* @param arrayLength the array length requested; use {@code -1} if not creating an array
* @throws InvalidClassException if it rejected by the filter or
@ -1333,11 +1337,12 @@ public class ObjectInputStream
*/
private void filterCheck(Class<?> clazz, int arrayLength)
throws InvalidClassException {
// Info about the stream is not available if overridden by subclass, return 0
long bytesRead = (bin == null) ? 0 : bin.getBytesRead();
RuntimeException ex = null;
ObjectInputFilter.Status status = null;
if (serialFilter != null) {
RuntimeException ex = null;
ObjectInputFilter.Status status;
// Info about the stream is not available if overridden by subclass, return 0
long bytesRead = (bin == null) ? 0 : bin.getBytesRead();
try {
status = serialFilter.checkInput(new FilterValues(clazz, arrayLength,
totalObjectRefs, depth, bytesRead));
@ -1355,12 +1360,24 @@ public class ObjectInputStream
status, clazz, arrayLength, totalObjectRefs, depth, bytesRead,
Objects.toString(ex, "n/a"));
}
if (status == null ||
status == ObjectInputFilter.Status.REJECTED) {
InvalidClassException ice = new InvalidClassException("filter status: " + status);
ice.initCause(ex);
throw ice;
}
}
DeserializationEvent event = new DeserializationEvent();
if (event.shouldCommit()) {
event.filterConfigured = serialFilter != null;
event.filterStatus = status != null ? status.name() : null;
event.type = clazz;
event.arrayLength = arrayLength;
event.objectReferences = totalObjectRefs;
event.depth = depth;
event.bytesRead = bytesRead;
event.exceptionType = ex != null ? ex.getClass() : null;
event.exceptionMessage = ex != null ? ex.getMessage() : null;
event.commit();
}
if (serialFilter != null && (status == null || status == ObjectInputFilter.Status.REJECTED)) {
InvalidClassException ice = new InvalidClassException("filter status: " + status);
ice.initCause(ex);
throw ice;
}
}