RFR(S): 8151259: [TESTBUG] nsk/jvmti/RedefineClasses/redefclass030 fails with "unexpected values of outer fields of the class" when running with -Xcomp
serguei.spitsyn at oracle.com
serguei.spitsyn at oracle.com
Tue Jul 24 00:22:27 UTC 2018
Hi Chris,
On 7/23/18 11:40, Chris Plummer wrote:
> Hi Serguei,
>
> If the fix was complicated I would agree, but it really just boils
> down to this one line change:
>
> - fire = -1;
> + fire = 0; // Ignore this compilation. Wait for next one.
It is not obvious that this will completely fix the problem.
Is it possible that there will not be next compilation with the -Xcomp?
If it is possible then it is better to explicitly exclude these tests
for -Xcomp.
Otherwise, consider this reviewed.
>
> Given that, I see no reason not to increase our test coverage by
> supporting this test during -Xcomp runs.
I'd agree if it is going to be stable.
Thanks,
Serguei
>
> thanks,
>
> Chris
>
> On 7/23/18 9:44 AM, serguei.spitsyn at oracle.com wrote:
>> Hi Chris,
>>
>> Would it be more simple to avoid running these tests with -Xcomp?
>> I guess, this would work: @requires vm.compMode != "Xcomp"
>>
>> Thanks,
>> Serguei
>>
>>
>> On 7/23/18 00:42, Chris Plummer wrote:
>>> Hello,
>>>
>>> Please review the following fix for JDK11:
>>>
>>> https://bugs.openjdk.java.net/browse/JDK-8151259
>>> http://cr.openjdk.java.net/~cjplummer/8151259/webrev.00
>>>
>>> It fixes the following 3 tests:
>>>
>>> vmTestbase/nsk/jvmti/RedefineClasses/redefclass028.java
>>> vmTestbase/nsk/jvmti/RedefineClasses/redefclass029.java
>>> vmTestbase/nsk/jvmti/RedefineClasses/redefclass030.java
>>>
>>> Any of which could fail when run with -Xcomp with (followed by a
>>> bunch more errors):
>>>
>>> # ERROR: Redefinition not started. Maybe running with -Xcomp. Test
>>> ignored.
>>>
>>> Although lately we've only seen this with redefclass030.java on macosx.
>>>
>>> These 3 tests do redefinition of a "hot" method after triggering
>>> compilation for it. After the redef some testing is done to ensure
>>> that the redef was done correctly, but the issue these test have
>>> actually comes before any redef is done.
>>>
>>> The test attempts to trigger compilation by calling a hot method a
>>> lot. The agent detects compilation by receiving a CompiledMethodLoad
>>> event. There was an issue discovered long ago that when -Xcomp is
>>> used, the compilation happens before the "hot" method is ever
>>> called. Then the redef would happen before compilation, and this
>>> somehow messed up the test (I'm not exactly sure how). The fix was
>>> to basically abandon the redef attempt when this problem is
>>> detected, and then supposedly just let the test run to completion
>>> (skipping the actual testing of the redef). After this change, if
>>> you ran with -Xcomp it would pass, but if you looked in the log you
>>> would see:
>>>
>>> # ERROR: Redefinition not started. Maybe running with -Xcomp. Test
>>> ignored.
>>>
>>> However, there was a bug in the logic to make the test run to
>>> completion, and also causes the above message to not appear. Instead
>>> the test would fail with:
>>>
>>> # ERROR: Redefinition not completed.
>>>
>>> Followed by a bunch more error message during the part of the test
>>> that checks if the redef was done properly.
>>>
>>> If the CompiledMethodLoad event comes in before the hot method is
>>> ever called (which it does with -Xcomp), the test sets fire = -1. If
>>> the hot method was called, it is set to 1. The setting of fire = -1
>>> was added to fix the -Xcomp problem mentioned above. The jvmti agent
>>> does the following:
>>>
>>> do {
>>> THREAD_sleep(1);
>>> /* wait for compilation to happen */
>>> } while(fire == 0);
>>>
>>> if (fire == 1) {
>>> /* do the redef here */
>>> NSK_DISPLAY0("agentProc: <<<<<<<< RedefineClasses() is
>>> successfully done\n");
>>> } else {
>>> // fire == -1
>>> NSK_DISPLAY0("agentProc: \"hot\" method wasn't executed.
>>> Don't perform redefinition\n");
>>> }
>>>
>>> The agent then syncs with the debuggee, waiting for it finish up.
>>> What the test expects is that waitForRedefinitionStarted() in the
>>> debuggee will time out after two seconds while waiting for fire == 1
>>> (which it thinks will will always happen because it was set to -1).
>>> When it times out, the test does appear to exit properly with, but
>>> with the following in the log, which is intended:
>>>
>>> # ERROR: Redefinition not started. Maybe running with -Xcomp. Test
>>> ignored.
>>>
>>> However, sometimes before waitForRedefinitionStarted() times out,
>>> the hot method is called enough times to trigger compilation. So
>>> another CompiledMethodLoad event arrives, and this time fire is set
>>> to 1. Because of this, waitForRedefinitionStarted() doesn't time out
>>> and returns with an indication that the redef has started. After
>>> this waitForRedefinitionCompleted() is executed. It waits for the
>>> redef to complete, but it never does since the agent decided not to
>>> do the redef when it saw fire == -1. So
>>> waitForRedefinitionCompleted() times out after 10 seconds and the
>>> test fails, with:
>>>
>>> # ERROR: Redefinition not completed.
>>>
>>> Actually the above error is not really what causes the failure. When
>>> the above error is detected, no error status is set and the test
>>> continues as if the redef had been done. So then the logic that
>>> detects if the redef was done properly ends up failing, and that's
>>> where the test actually indicates a failure status. You see a whole
>>> bunch of other errors in the log because of all the checks that fail.
>>>
>>> The fix is to not abandon the test when the first CompiledMethodLoad
>>> event is before the hot method was called. Instead just leave
>>> fire==0 and wait for the next CompiledMethodLoad event that is
>>> triggered after the method is called enough times to be recompiled.
>>> I'm not sure why it was not originally done this way. Possibly the
>>> recompilation did not happen reliably, but I have not run into this
>>> problem. The other changes in redefclass030.c are just cleaning up
>>> debug tracing.
>>>
>>> Another fix was to properly set the error status when
>>> waitForRedefinitionStarted() or waitForRedefinitionCompleted() times
>>> out, although this is just a safety net and I didn't run into any
>>> cases where this happened after fixing the CompiledMethodLoad event
>>> handling. So in general the changes in redefclass030.java were not
>>> needed, but provide better error handling.
>>>
>>> thanks,
>>>
>>> Chris
>>>
>>
>
>
More information about the serviceability-dev
mailing list