On Thu, 3 Dec 2020 12:55:04 GMT, Per Liden <pli...@openjdk.org> wrote:

> This PR replaces the withdrawn PR #1348. This PR tries to fix the underlying 
> problem, rather than fix the tests.
> 
> The problem is that a number of JDI tests create objects on the debugger side 
> with calls to `newInstance()`. However, on the debugee side, these new 
> instances will only be held on to by a `JNIGlobalWeakRef`, which means they 
> could be collected at any time, even before `newInstace()` returns. A number 
> of JDI tests get spurious `ObjectCollectedException` thrown at them, which 
> results in test failures. To make these objects stick around, a call to 
> `disableCollection()` is typically needed.
> 
> However, as pointer out by @plummercj in 
> [JDK-8255987](https://bugs.openjdk.java.net/browse/JDK-8255987):
> 
>> Going back to the spec, ObjectReference.disableCollection() says:
>> 
>> "By default all ObjectReference values returned by JDI may be collected at 
>> any time the target VM is running"
>> 
>> and
>> 
>> "Note that while the target VM is suspended, no garbage collection will 
>> occur because all threads are suspended."
>> 
>> But no where does is say what is meant by the VM running or being suspended, 
>> or how to get it in that state. One might assume that this ties in with 
>> VirtualMachine.suspend(), but it says:
>> 
>> "Suspends the execution of the application running in this virtual machine. 
>> All threads currently running will be suspended."
>> 
>> No mention of suspending the VM, but that certainly seems to be what is 
>> implied by the method name and also by the loose wording in 
>> disableCollection().
> 
> Most of our spuriously failing tests do actually make a call to 
> `VirtualMachine.suspend()`, presumably to prevent objects from being garbage 
> collected. However, the current implementation of `VirtualMachine.suspend()` 
> will only suspend all Java threads. That is not enough to prevent objects 
> from being garbage collected. The GC can basically run at any time, and there 
> is no relation to whether all Java threads are suspended or not.
> 
> However, as suggested by @plummercj, we could emulate the behaviour implied 
> by the spec by letting a call to `VirtualMachine.suspend()` also convert all 
> existing JDI objects references to be backed by a (strong) `JNIGlobalRef` 
> rather than a (weak) `JNIGlobalWeakRef`. That will not prevent the GC from 
> running, but it will prevent any object visible to a JDI client from being 
> garbage collected. Of course, a call to `VirtualMachine.resume()` would 
> convert all references back to being weak again.
> 
> This patch introduces the needed functions in `libjdwp` to "pin" and "unpin" 
> all objects. These new functions are then used by the underpinnings of 
> `VirtualMachine.suspend()` and `VirtualMachine.resume()` to implement the 
> behaviour described above.
> 
> Note that there are still a few tests that needed adjustments to guard 
> against `ObjectCollectionException`. These are:
>  - *vmTestbase/nsk/jdi/ArrayType/newInstance/newinstance004.java* - This test 
> seems to have been forgotten by 
> [JDK-8203174](https://bugs.openjdk.java.net/browse/JDK-8203174), which did a 
> similar fix in the other `ArrayType/newinstance` tests.
>  - 
> *vmTestbase/nsk/jdi/VMOutOfMemoryException/VMOutOfMemoryException001/VMOutOfMemoryException001.java*
>  - We just want to allocate as much as we can, so catching an ignoring 
> `ObjectCollectedException` seems reasonable here.
>  - *vmTestbase/nsk/share/jdi/sde/SDEDebuggee.java* - We still want to prevent 
> `TestClassLoader` from being unloaded to avoid invalidating code locations.
>  - 
> *vmTestbase/nsk/jdi/ReferenceType/instances/instances002/instances002.java* - 
> This test keeps the VM suspended, and then expects objects to be garbage 
> collected, which they now won't.
> 
> Testing:
> - More than 50 iterations of the `vmTestbase/nsk/jdi` and 
> `vmTestbase/nsk/jdwp` test suites, using various GC, both in mach5 and 
> locally.

This pull request has now been integrated.

Changeset: 79f1dfb8
Author:    Per Liden <pli...@openjdk.org>
URL:       https://git.openjdk.java.net/jdk/commit/79f1dfb8
Stats:     168 lines in 8 files changed: 135 ins; 0 del; 33 mod

8255987: JDI tests fail with com.sun.jdi.ObjectCollectedException

Reviewed-by: dholmes, cjplummer

-------------

PR: https://git.openjdk.java.net/jdk/pull/1595

Reply via email to