On 27 nov 2013, at 12:21, David Holmes <david.hol...@oracle.com> wrote:
> On 27/11/2013 8:46 PM, Mattias Tobiasson wrote: >> Hi, I now have a reproducer for this test that fails every time. >> I just need to verify that it really is a test bug and not a product bug. >> >> This is a summary of the test: >> 1. It loads a javaagent jar that implements ClassFileTransformer. >> 2. The agent loads class java.math.BigInteger and expects a callback to >> ClassFileTransformer.transform(). But it sometimes does not get that >> callback. >> >> I believe the reason for the intermittent failures are that the jvm flag >> -Xshare have different default values on different servers. > > -Xshare:auto will default to off for server compiler, but on for client > >> When the reproducer is run with flag "-Xshare:off" it passes every time. >> When run with "-Xshare:auto" it fails every time. >> When the reproducer is changed to use a dummy class (RedefineDummy) instead >> of BigInteger, then the test passes every time no matter what value -Xshare >> has. >> >> My proposed fix for the bug is to use a dummy class instead of BigInteger. I >> just need to verify that it is ok that ClassFileTransformer.transform() is >> NOT called for BigInteger when -Xshare is enabled. > > If the whole point of the test is to transform a file from the shared archive > then changing to a class not in the archive will defeat that. So you need to > verify what the intent of the test is. There is nothing in the test that expects class data sharing to be tested. The test is a basic verification of the attach mechanism. As far as I can tell, It is expected that ClassFileTransformer.transform() is not called for classes in the shared archive (BigInteger) in this case. Thus, I think it is a good idea to either use a different class or to explicitly disable class data sharing (simpler). /Staffan > > David > >> >> >> The reproducer is shown below. It loads the javaagent into its own vm so I >> don't need to set up multiple jvms. >> >> public class TestRedefine implements ClassFileTransformer { >> >> public static void agentmain(String agentArgs, Instrumentation inst) >> throws Throwable { >> try { >> inst.addTransformer(new TestRedefine()); >> >> ClassLoader.getSystemClassLoader().loadClass("java.math.BigInteger"); >> if (!isTransformCalled) { >> throw new Exception("transform() NOT called for " + >> targetName); >> } >> } catch (Throwable t) { >> t.printStackTrace(); >> throw t; >> } >> } >> >> public byte[] transform(ClassLoader loader, >> String className, >> Class<?> classBeingRedefined, >> ProtectionDomain protectionDomain, >> byte[] classfileBuffer) { >> System.out.println("transform called: " + className); >> if (className.equals("java/math/BigInteger")) { >> isTransformCalled = true; >> } >> return null; >> } >> >> public static void main(String args[]) throws Exception { >> String pid = getProcessId(); >> try { >> VirtualMachine vm = VirtualMachine.attach(pid); >> vm.loadAgent("TestRedefine.jar"); >> } catch (Exception e) { >> e.printStackTrace(); >> throw e; >> } >> } >> >> ... more code ... >> } >> >> >> >> >> >> ----- Original Message ----- >> From: leonid.mes...@oracle.com >> To: mattias.tobias...@oracle.com >> Cc: serviceability-dev@openjdk.java.net >> Sent: Wednesday, November 27, 2013 9:19:37 AM GMT +01:00 Amsterdam / Berlin >> / Bern / Rome / Stockholm / Vienna >> Subject: Re: RFR (S): 6461635: [TESTBUG] BasicTests.sh test fails >> intermittently >> >> Hi >> >> Generally I am ok with your comments and fix. However you still needed >> to get official review. >> >> The only question is about failure related from retransformation of >> j.l.BigInteger with CDS. >> Could it be JDK issue? In this case it would be better to file it as a >> part of fix. >> I understand that using of CDS and instrumentation of JDK classes is not >> related with this test >> and your fix make it cleaner. However could you please verify that we >> don't have JDK issue here. >> >> see other comments inline >> >> On 11/26/2013 08:35 PM, Mattias Tobiasson wrote: >>> Hi, >>> Thanks for the review. I have summarized the questions and answers: >>> >>> Q: What is the reason of this intermittent failure? >>> A: The test expects the callback ClassFileTransformer.transform() to be >>> called when it loads a new class. That function does not seem to be called >>> when class sharing is enabled and a previous test has called >>> "-Xshare:dump". I am not really sure how ClassFileTransformer works >>> together with class sharing. >>> I got the idea for -Xshare:dump from this bug: >>> https://bugs.openjdk.java.net/browse/JDK-6571866 >>> I have verified on jprt that it fails without that flag. I have not been >>> able to reproduce a failure when -Xshare:off is set. >>> >>> Having thought more about the problem, I would like to use another fix. The >>> test currently uses java.lang.BigInteger for the transform test. I want to >>> change that and instead use my own class (RedefineDummy.java). Since >>> loading my own class is not affected by -Xshare, I do not need to set the >>> flag. >> >>> >>> Q: You used "output" in finally which is not initialized properly in the >>> case of Exception. Could we get another uncaught exception in finally? >>> A: output is only sent to getProcessLog() to get a log message. That >>> function can handle null values, which it just logs as "null". >> Thank you for explanation. >>> >>> Q: In getCommandLine(), should we also trim cmd to remove last " "? >>> A: Yes. I will fix that. I will also add a check if ProcessBuilder is null. >> Ok >>> >>> Q: waitForJvmPid(String key) throws Throwable. Why throw throwable? >>> A: I think there are so many things that can go wrong when starting a >>> separate java process, that I do not want to check for expected errors. I >>> also don't know how a test writer should handle different kind of >>> exceptions from this function. Any exception is logged in the sub function. >> >>> >>> Q: Should tryFindJvmPid(String key) be private? Are we going to use it in >>> tests or only waitForJvmPid? >>> A: Yes, that function may also be used by tests. It is currently not used >>> by any test, but it might be useful. >> Ok >>> >>> Q: Timeouts in function waitForJvmPid(String key)? >>> A: I definitely agree of the problem. The reason for not adding a timeout >>> parameter to the function is that I do not want the tests to be responsible >>> for setting hard coded timeouts. Timeouts should be handled by the >>> framework. I know there are plans of adding better process handling to >>> jtreg (with ProcessHandler). After that jtreg should be better at handling >>> timeouts. >>> I will add a flush() to stdout to make sure we log before we wait. >> Hope we will update jtreg before get into this issue :) >> >> Leonid >>> Mattias >>> >>> ----- Original Message ----- >>> From: leonid.mes...@oracle.com >>> To: mattias.tobias...@oracle.com, serviceability-dev@openjdk.java.net >>> Sent: Monday, November 25, 2013 6:26:27 PM GMT +01:00 Amsterdam / Berlin / >>> Bern / Rome / Stockholm / Vienna >>> Subject: Re: RFR (S): 6461635: [TESTBUG] BasicTests.sh test fails >>> intermittently >>> >>> Hi >>> >>> I have a couple of high-level questions. >>> >>> On 11/25/2013 08:28 PM, Mattias Tobiasson wrote: >>>> Hi, >>>> The test has been updated after the first review. >>>> The two java files for each test has been merged to a single file. >>>> >>>> >>>> Updated summary of changes: >>>> 1. The real test bug fix is to add flag "-Xshare:off" when starting the >>>> "Application" instance. Without that flag, the test for >>>> ClassFileTransformer in RedefineAgent.java fails intermittently. The flag >>>> is added in function startApplication() in RunnerUtil.java. >>> What is the reason of this intermittent failure? >>>> 2. Removed all bash scripts. >>> Great! >>>> 3. Merged the setup bash script and the java test code for each test to a >>>> single java file. The old java test code is unchanged, it has just been >>>> moved to static nested class in the new java setup file. >>>> >>>> 4. Added some utility functions to jdk/testlibrary. >>> Here some comments about library code. >>> http://cr.openjdk.java.net/~miauno/6461635/webrev.01/jdk/test/lib/testlibrary/jdk/testlibrary/ProcessThread.java.udiff.html >>> >>> + try { >>> + output = new OutputAnalyzer(this.process); >>> + } catch (Throwable t) { >>> + String name = Thread.currentThread().getName(); >>> + System.out.println(String.format("ProcessThread[%s] >>> failed: %s", name, t.toString())); >>> + throw t; >>> + } finally { >>> + String logMsg = ProcessTools.getProcessLog(processBuilder, >>> output); >>> + System.out.println(logMsg); >>> + } >>> >>> >>> You used output in finally which is not initialized properly in the case >>> of Exception. >>> Could we get another uncaught exception in finally? >>> >>> http://cr.openjdk.java.net/~miauno/6461635/webrev.01/jdk/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java.udiff.html >>> >>> 1) Same in as previous in executeProcess method. >>> >>> 2) getCommandLine (...) >>> >>> + /** >>> + * @return The full command line for the ProcessBuilder. >>> + */ >>> + public static String getCommandLine(ProcessBuilder pb) { >>> + StringBuilder cmd = new StringBuilder(); >>> + for (String s : pb.command()) { >>> + cmd.append(s).append(" "); >>> + } >>> + return cmd.toString(); >>> + } >>> >>> >>> Should we also trim cmd to remove last " "? >>> >>> http://cr.openjdk.java.net/~miauno/6461635/webrev.01/jdk/test/lib/testlibrary/jdk/testlibrary/Utils.java.udiff.html >>> >>> public static int waitForJvmPid(String key) throws Throwable { >>> >>> >>> Why it throw Trowable? Could we deal with exceptions in this method and >>> re-throw some more meaningful exception here? >>> Could you force flush for out here: >>> >>> System.out.println("waitForJvmPid: Waiting for key '" + key + "'"); >>> >>> Hope it should be enough. It is scary to investigate such "timeouts". >>> Would it be better to add some >>> internal timeout in testlibrary? Really jtreg doesn't kill all processes >>> and we have alive java processes in such case. >>> For samevm tests timeouts are even worse. There is no good way to kill >>> test in samevm. >>> >>> Should be >>> >>> public static int tryFindJvmPid(String key) throws Throwable { >>> >>> private? Are we going to use it in tests or only waitForJvmPid? >>> >>> Leonid >>>> 5. Moved exit code check from the common utility function in >>>> ProcessThread.java to the test JstatdTest.java. The check is moved to the >>>> test because other tests in the future may have other expected exit codes. >>>> >>>> >>>> Webrev: >>>> http://cr.openjdk.java.net/~miauno/6461635/webrev.01/ >>>> >>>> Bug: >>>> https://bugs.openjdk.java.net/browse/JDK-6461635 >>>> >>>> Mattias >>>> >>>> >>>> ----- Original Message ----- >>>> From: mattias.tobias...@oracle.com >>>> To: mikael.a...@oracle.com >>>> Cc: serviceability-dev@openjdk.java.net, alan.bate...@oracle.com >>>> Sent: Thursday, November 21, 2013 9:22:11 AM GMT +01:00 Amsterdam / Berlin >>>> / Bern / Rome / Stockholm / Vienna >>>> Subject: Re: RFR (S): 6461635: [TESTBUG] BasicTests.sh test fails >>>> intermittently >>>> >>>> I agree that merging both files in a single file may be good. >>>> The main reason why I did not do that is that I wanted to keep the history >>>> of the existing test. If I copy the test to a new file, all history of the >>>> code is lost. >>>> >>>> But this test bug was reported 8 years ago, and I don't believe much has >>>> changed in the code since then. So keeping the history may not be that >>>> important. >>>> >>>> Mattias >>>> >>>> ----- Original Message ----- >>>> From: mikael.a...@oracle.com >>>> To: mattias.tobias...@oracle.com, alan.bate...@oracle.com >>>> Cc: serviceability-dev@openjdk.java.net >>>> Sent: Wednesday, November 20, 2013 4:11:45 PM GMT +01:00 Amsterdam / >>>> Berlin / Bern / Rome / Stockholm / Vienna >>>> Subject: Re: RFR (S): 6461635: [TESTBUG] BasicTests.sh test fails >>>> intermittently >>>> >>>> How about defining the class that you want to attach to as a static >>>> inner class to the actual test? That would give you only one file, but >>>> with two classes, each with its own main method and clear correlation >>>> between them. >>>> >>>> Mikael >>>> >>>> On 2013-11-20 15:41, Mattias Tobiasson wrote: >>>>> Hi, >>>>> Each test requires 2 files, the actual test code and a helper file. >>>>> >>>>> The helper file will launch a separate java process (called Application), >>>>> and then start the actual test. The actual test will then attach to the >>>>> Application. >>>>> >>>>> For example: >>>>> PermissionTests.sh: Helper file that will launch Application instance and >>>>> then start PermissionTest.java >>>>> PermissionTest.java: The actual test code that attaches to the >>>>> Application. >>>>> >>>>> It is the PermissionTests.sh that is started by jtreg (contains the >>>>> "@test"-tag). >>>>> >>>>> When I port PermissionTest.sh to java I would get 2 files called >>>>> PermissionTest.java, so some name change is required. >>>>> >>>>> I could have kept the old PermissionTest.java unchanged, but then I would >>>>> need another name for the prevoius PermissionTest.sh. And I wanted a >>>>> "clean" Test name for the file containing the "@test"-tag. >>>>> >>>>> I used these names: >>>>> TestPermission.java: Helper file. >>>>> TestPermissionImpl.java: Actual test code. >>>>> >>>>> I am still new to adding tests for open jdk. I am happy to change the >>>>> names if they do not follow the naming convention. >>>>> >>>>> Mattias >>>>> >>>>> >>>>> ----- Original Message ----- >>>>> From: alan.bate...@oracle.com >>>>> To: mattias.tobias...@oracle.com >>>>> Cc: serviceability-dev@openjdk.java.net >>>>> Sent: Wednesday, November 20, 2013 2:50:52 PM GMT +01:00 Amsterdam / >>>>> Berlin / Bern / Rome / Stockholm / Vienna >>>>> Subject: Re: RFR (S): 6461635: [TESTBUG] BasicTests.sh test fails >>>>> intermittently >>>>> >>>>> >>>>> Out of curiosity, what is the reason for the rename? I ask because we >>>>> use Basic and similar names in many areas. Also anything in the test >>>>> tree should be a test. >>>>> >>>>> -Alan. >>>>> >>>>> On 20/11/2013 13:47, Mattias Tobiasson wrote: >>>>>> Hi, >>>>>> Could you please review this fix. >>>>>> >>>>>> Summary of changes: >>>>>> >>>>>> 1. The real test bug fix is to add flag "-Xshare:off" when starting the >>>>>> "Application" instance. Without that flag, the test for >>>>>> ClassFileTransformer in RedefineAgent.java fails intermittently. The >>>>>> flag is added in function startApplication() in RunnerUtil.java. >>>>>> >>>>>> 2. Ported the following bash scripts to java: >>>>>> BasicTests.sh -> TestBasic.java >>>>>> PermissionTests.sh -> TestPermission.java >>>>>> ProviderTests.sh -> TestProvider.java >>>>>> >>>>>> 3. Renamed the java test code to avoid name clash with new java classes >>>>>> ported from bash script: >>>>>> BasicsTest.java -> TestBasicImpl.java >>>>>> PermissionTest.java -> TestPermissionImpl.java >>>>>> ProviderTest.java -> TestProviderImpl.java >>>>>> >>>>>> 4. Added some utility functions to jdk/testlibrary. >>>>>> >>>>>> 5. Moved exit code check from the common utility function in >>>>>> ProcessThread.java to the test JstatdTest.java. The check is moved to >>>>>> the test because other tests in the future may have other expected exit >>>>>> codes. >>>>>> >>>>>> >>>>>> Thanks, >>>>>> Mattias >>>>>> >>>>>> Webrev: >>>>>> http://cr.openjdk.java.net/~miauno/6461635/webrev.00/ >>>>>> >>>>>> Bug: >>>>>> https://bugs.openjdk.java.net/browse/JDK-6461635 >>> >> >>