8222422: vmTestbase/nsk/jdi/ClassLoaderReference/definedClasses tests failed with Unexpected Exception: null

Daniil Titov daniil.x.titov at oracle.com
Sat May 11 17:14:22 UTC 2019


Hi David,

There are two ways how these reference types (for the classes that become unloaded later) could appear in the collection com.sun.tools.jdi.VirtualMachineImpl maintains  and stores in  VirtualMachineImpl.typesBySignature instance variable:
1) Initial load when all classes are requested from the debuggee
2) Or added later when ClassPrepare event for a specific class is posted and handled

The reference types are removed from VirtualMachineImpl.typesBySignature  when ClassUnload event is processed. However, additional tracing showed ( pleases see below the sample output) that in some cases these ClassUnload events are received after we entered definedClasses() method and  started iterating over the copy of the collection of the classes returned by vm.allClasses() method.

Based on the output below it seems as all unloaded classes are the generated ones or lambda forms. 
 
--> debugger: ......getting: List definedClasses = clRef.definedClasses();

Received Unload Event for Ljdk/internal/reflect/GeneratedConstructorAccessor1;
Handled Unload Event for Ljdk/internal/reflect/GeneratedConstructorAccessor1;
Received Unload Event for Lorg/graalvm/compiler/lir/alloc/lsra/LinearScanLifetimeAnalysisPhase$$Lambda$93/1045689388;
Handled Unload Event for Lorg/graalvm/compiler/lir/alloc/lsra/LinearScanLifetimeAnalysisPhase$$Lambda$93/1045689388;
Received Unload Event for Ljava/lang/invoke/LambdaForm$DMH/733189374;
Handled Unload Event for Ljava/lang/invoke/LambdaForm$DMH/733189374;
Received Unload Event for Lorg/graalvm/compiler/lir/alloc/lsra/LinearScanLifetimeAnalysisPhase$$Lambda$94/454340234;
Handled Unload Event for Lorg/graalvm/compiler/lir/alloc/lsra/LinearScanLifetimeAnalysisPhase$$Lambda$94/454340234;
Received Unload Event for Ljava/lang/invoke/LambdaForm$DMH/1780167778;
Handled Unload Event for Ljava/lang/invoke/LambdaForm$DMH/1780167778;
Received Unload Event for Lorg/graalvm/compiler/lir/alloc/lsra/LinearScanLifetimeAnalysisPhase$$Lambda$86/323001064;
Handled Unload Event for Lorg/graalvm/compiler/lir/alloc/lsra/LinearScanLifetimeAnalysisPhase$$Lambda$86/323001064;

Exception while getting classloader for type jdk.internal.reflect.GeneratedConstructorAccessor1
# ERROR: ##> debugger: ERROR: Exception : com.sun.jdi.ObjectCollectedException


Thanks!
--Daniil



On 5/11/19, 3:39 AM, "David Holmes" <david.holmes at oracle.com> wrote:

    On 11/05/2019 2:14 pm, Jean Christophe Beyler wrote:
    > Isn't that the point? The list returned could have unloaded classes  and 
    > we can catch it via this exception (from the comment above 
    > the ReferenceType interface):
    > 
    >   * Any method on <code>ReferenceType</code> or which directly or 
    > indirectly takes
    >   * <code>ReferenceType</code> as parameter may throw
    >   * {@link ObjectCollectedException} if the mirrored type has been unloaded.
    > 
    > Turns out that even in the definedClasses, we can get that exception so 
    > we should check for it while walking the reference types as well?
    
    I understand that the list returned to the "debugger" process may 
    contain ReferenceTypes for types that have actually been unloaded by the 
    time it queries them (unless the debuggee is suspended of course). But I 
    don't see how we can encounter those types while compiling the list in 
    the debuggee in the first place.
    
    Something seems amiss here ... possibly just my understanding ...
    
    David
    
    > Jc
    > 
    > *From: *Chris Plummer <chris.plummer at oracle.com 
    > <mailto:chris.plummer at oracle.com>>
    > *Date: *Fri, May 10, 2019 at 9:09 PM
    > *To: *David Holmes, Daniil Titov, OpenJDK Serviceability
    > 
    >     On 5/10/19 9:03 PM, Chris Plummer wrote:
    >      > On 5/10/19 8:59 PM, David Holmes wrote:
    >      >> Hi Daniil,
    >      >>
    >      >> On 11/05/2019 12:10 pm, Daniil Titov wrote:
    >      >>> Please review the change that fixes an intermittent failure of the
    >      >>> test.
    >      >>>
    >      >>> The tests checks the implementation of  the
    >      >>> com.sun.tools.jdi.ClassLoaderReference class. The problem here is
    >      >>> that while
    >      >>> com.sun.tools.jdi.ClassLoaderReferenceImpl.definedClasses()
    >     iterates
    >      >>> over all loaded classes to retrieve a classloader and compares
    >     it to
    >      >>> the current one, some of the classes might become unloaded and
    >      >>> garbage collected (e.g.
    >      >>> org.graalvm.compiler.nodes.InliningLog$$Lambda$41.899832640 or
    >      >>> jdk.internal.reflect.GeneratedConstructorAccessor1, etc.). If this
    >      >>> happens then the attempt to retrieve a classloader for the
    >     collected
    >      >>> class results in com.sun.jdi.ObjectCollectedException being thrown.
    >      >>
    >      >> That seems odd to me. If you have a reference to the Class then it
    >      >> can't be unloaded. I would not expect allClasses() to have
    >      >> weak-references, so a class should not be unloadable while you are
    >      >> examining it. Unless it is finding VM anonymous classes (which it
    >      >> should not!).
    >      >>
    >      > I was just typing up something similar. Shouldn't the test do a
    >      > vm.suspend() and then call disableCollection() on each class
    >     returned
    >      > by vm.allClasses()?
    >     Oh wait, this isn't a test. It's part of JDI. I guess it would be up to
    >     the user of ClassLoaderReference.definedClasses() to do the suspend. In
    >     fact I'm not sure there's much purpose in calling
    >     ClassLoaderReference.definedClasses() without suspending first. Even
    >     with your changes, the list returned can end up with references to
    >     unloaded classes.
    > 
    >     Chris
    >      >
    >      > Chris
    >      >> David
    >      >> -----
    >      >>
    >      >>> The fix catches this com.sun.jdi.ObjectCollectedException and
    >      >>> continues iterating over the rest of the classes.
    >      >>>
    >      >>> Webrev: http://cr.openjdk.java.net/~dtitov/8222422/webrev.01
    >      >>> Bug: https://bugs.openjdk.java.net/browse/JDK-8222422
    >      >>>
    >      >>> Thanks!
    >      >>> --Daniil
    >      >>>
    >      >>>
    >      >
    >      >
    > 
    > 
    > 
    > 
    > -- 
    > 
    > Thanks,
    > Jc
    




More information about the serviceability-dev mailing list