products/sources/formale Sprachen/Java/openjdk-20-36_src/test/jdk/com/sun/jdi image not shown  

Quellcode-Bibliothek

© Kompilation durch diese Firma

[Weder Korrektheit noch Funktionsfähigkeit der Software werden zugesichert.]

Datei: OomDebugTest.java   Sprache: JAVA

/*
 * Copyright (c) 2016 Red Hat Inc.
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */


/**
 *  @test
 *  @bug 8153711
 *  @summary JDWP: Memory Leak (global references not deleted after invokeMethod).
 *
 *  @author Severin Gehwolf <[email protected]>
 *
 *  @requires vm.gc != "Z"
 *  @library ..
 *  @run build TestScaffold VMConnection TargetListener TargetAdapter
 *  @run compile -g OomDebugTest.java
 *  @run main OomDebugTest OomDebugTestTarget test1
 *  @run main OomDebugTest OomDebugTestTarget test2
 *  @run main OomDebugTest OomDebugTestTarget test3
 *  @run main OomDebugTest OomDebugTestTarget test4
 *  @run main OomDebugTest OomDebugTestTarget test5
 */

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;

import com.sun.jdi.ArrayReference;
import com.sun.jdi.ArrayType;
import com.sun.jdi.ClassType;
import com.sun.jdi.Field;
import com.sun.jdi.InvocationException;
import com.sun.jdi.Method;
import com.sun.jdi.ObjectReference;
import com.sun.jdi.ReferenceType;
import com.sun.jdi.StackFrame;
import com.sun.jdi.VMOutOfMemoryException;
import com.sun.jdi.Value;
import com.sun.jdi.event.BreakpointEvent;
import com.sun.jdi.event.ExceptionEvent;

/***************** Target program **********************/

class OomDebugTestTarget {

    OomDebugTestTarget() {
        System.out.println("DEBUG: invoked constructor");
    }
    static class FooCls {
        @SuppressWarnings("unused")
        private byte[] bytes = new byte[3000000];
    };

    FooCls fooCls = new FooCls();
    byte[] byteArray = new byte[0];

    void testMethod(FooCls foo) {
        System.out.println("DEBUG: invoked 'void testMethod(FooCls)', foo == " + foo);
    }

    void testPrimitive(byte[] foo) {
        System.out.println("DEBUG: invoked 'void testPrimitive(byte[])', foo == " + foo);
    }

    byte[] testPrimitiveArrRetval() {
        System.out.println("DEBUG: invoked 'byte[] testPrimitiveArrRetval()'");
        return new byte[3000000];
    }

    FooCls testFooClsRetval() {
        System.out.println("DEBUG: invoked 'FooCls testFooClsRetval()'");
        return new FooCls();
    }

    public void entry() {}

    public static void main(String[] args){
        System.out.println("DEBUG: OomDebugTestTarget.main");
        new OomDebugTestTarget().entry();
    }
}

/***************** Test program ************************/

public class OomDebugTest extends TestScaffold {

    private static final String[] ALL_TESTS = new String[] {
            "test1""test2""test3""test4""test5"
    };
    private static final Set<String> ALL_TESTS_SET = new HashSet<String>();
    static {
        ALL_TESTS_SET.addAll(Arrays.asList(ALL_TESTS));
    }
    private static final String TEST_CLASSES = System.getProperty("test.classes"".");
    private static final File RESULT_FILE = new File(TEST_CLASSES, "results.properties");
    private static final String LAST_TEST = ALL_TESTS[ALL_TESTS.length - 1];
    private ReferenceType targetClass;
    private ObjectReference thisObject;
    private int failedTests;
    private final String testMethod;

    public OomDebugTest(String[] args) {
        super(args);
        if (args.length != 2) {
            throw new RuntimeException("Test failed unexpectedly.");
        }
        this.testMethod = args[1];
    }

    @Override
    protected void runTests() throws Exception {
        try {
            addListener(new TargetAdapter() {

                @Override
                public void exceptionThrown(ExceptionEvent event) {
                    String name = event.exception().referenceType().name();
                    System.err.println("DEBUG: Exception thrown in debuggee was: " + name);
                }
            });
            /*
             * Get to the top of entry()
             * to determine targetClass and mainThread
             */

            BreakpointEvent bpe = startTo("OomDebugTestTarget""entry""()V");
            targetClass = bpe.location().declaringType();

            mainThread = bpe.thread();

            StackFrame frame = mainThread.frame(0);
            thisObject = frame.thisObject();
            java.lang.reflect.Method m = findTestMethod();
            m.invoke(this);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
            failure();
        } catch (SecurityException e) {
            e.printStackTrace();
            failure();
        }
        /*
         * resume the target, listening for events
         */

        listenUntilVMDisconnect();
    }

    private java.lang.reflect.Method findTestMethod()
            throws NoSuchMethodException, SecurityException {
        return OomDebugTest.class.getDeclaredMethod(testMethod);
    }

    private void failure() {
        failedTests++;
    }

    /*
     * Test case: Object reference as method parameter.
     */

    @SuppressWarnings("unused"// called via reflection
    private void test1() throws Exception {
        System.out.println("DEBUG: ------------> Running test1");
        try {
            Field field = targetClass.fieldByName("fooCls");
            ClassType clsType = (ClassType)field.type();
            Method constructor = getConstructorForClass(clsType);
            for (int i = 0; i < 15; i++) {
                @SuppressWarnings({ "rawtypes""unchecked" })
                ObjectReference objRef = clsType.newInstance(mainThread,
                                                             constructor,
                                                             new ArrayList(0),
                                                             ObjectReference.INVOKE_NONVIRTUAL);
                if (objRef.isCollected()) {
                    System.out.println("DEBUG: Object got GC'ed before we can use it. NO-OP.");
                    continue;
                }
                invoke("testMethod""(LOomDebugTestTarget$FooCls;)V", objRef);
            }
        } catch (InvocationException e) {
            handleFailure(e);
        }
    }

    /*
     * Test case: Array reference as method parameter.
     */

    @SuppressWarnings("unused"// called via reflection
    private void test2() throws Exception {
        System.out.println("DEBUG: ------------> Running test2");
        try {
            Field field = targetClass.fieldByName("byteArray");
            ArrayType arrType = (ArrayType)field.type();

            for (int i = 0; i < 15; i++) {
                ArrayReference byteArrayVal = arrType.newInstance(3000000);
                if (byteArrayVal.isCollected()) {
                    System.out.println("DEBUG: Object got GC'ed before we can use it. NO-OP.");
                    continue;
                }
                invoke("testPrimitive""([B)V", byteArrayVal);
            }
        } catch (VMOutOfMemoryException e) {
            defaultHandleOOMFailure(e);
        }
    }

    /*
     * Test case: Array reference as return value.
     */

    @SuppressWarnings("unused"// called via reflection
    private void test3() throws Exception {
        System.out.println("DEBUG: ------------> Running test3");
        try {
            for (int i = 0; i < 15; i++) {
                invoke("testPrimitiveArrRetval",
                       "()[B",
                       Collections.EMPTY_LIST,
                       vm().mirrorOfVoid());
            }
        } catch (InvocationException e) {
            handleFailure(e);
        }
    }

    /*
     * Test case: Object reference as return value.
     */

    @SuppressWarnings("unused"// called via reflection
    private void test4() throws Exception {
        System.out.println("DEBUG: ------------> Running test4");
        try {
            for (int i = 0; i < 15; i++) {
                invoke("testFooClsRetval",
                       "()LOomDebugTestTarget$FooCls;",
                       Collections.EMPTY_LIST,
                       vm().mirrorOfVoid());
            }
        } catch (InvocationException e) {
            handleFailure(e);
        }
    }

    /*
     * Test case: Constructor
     */

    @SuppressWarnings({ "unused""unchecked""rawtypes" }) // called via reflection
    private void test5() throws Exception {
        System.out.println("DEBUG: ------------> Running test5");
        try {
            ClassType type = (ClassType)thisObject.type();
            for (int i = 0; i < 15; i++) {
                type.newInstance(mainThread,
                                 findMethod(targetClass, """()V"),
                                 new ArrayList(0),
                                 ObjectReference.INVOKE_NONVIRTUAL);
            }
        } catch (InvocationException e) {
            handleFailure(e);
        }
    }

    private Method getConstructorForClass(ClassType clsType) {
        List<Method> methods = clsType.methodsByName("");
        if (methods.size() != 1) {
            throw new RuntimeException("FAIL. Expected only one, the default, constructor");
        }
        return methods.get(0);
    }

    private void handleFailure(InvocationException e) {
        // There is no good way to see the OOME diagnostic message in the target since the
        // TestScaffold might throw an exception while trying to print the stack trace. I.e
        // it might get a VMDisconnectedException before the stack trace printing finishes.
        System.err.println("FAILURE: InvocationException thrown. Trying to determine cause...");
        defaultHandleOOMFailure(e);
    }

    private void defaultHandleOOMFailure(Exception e) {
        e.printStackTrace();
        failure();
    }

    @SuppressWarnings({ "rawtypes""unchecked" })
    void invoke(String methodName, String methodSig, Value value)
            throws Exception {
        List args = new ArrayList(1);
        args.add(value);
        invoke(methodName, methodSig, args, value);
    }

    void invoke(String methodName,
                String methodSig,
                @SuppressWarnings("rawtypes") List args,
                Value value) throws Exception {
        Method method = findMethod(targetClass, methodName, methodSig);
        if ( method == null) {
            failure("FAILED: Can't find method: "
                    + methodName  + " for class = " + targetClass);
            return;
        }
        invoke(method, args, value);
    }

    @SuppressWarnings({ "rawtypes""unchecked" })
    void invoke(Method method, List args, Value value) throws Exception {
        thisObject.invokeMethod(mainThread, method, args, 0);
        System.out.println("DEBUG: Done invoking method via debugger.");
    }

    Value fieldValue(String fieldName) {
        Field field = targetClass.fieldByName(fieldName);
        return thisObject.getValue(field);
    }

    // Determine the pass/fail status on some heuristic and don't fail the
    // test if < 3 of the total number of tests (currently 5) fail. This also
    // has the nice side effect that all tests are first attempted and only
    // all tests ran an overall pass/fail status is determined.
    private static void determineOverallTestStatus(OomDebugTest oomTest)
                                   throws IOException, FileNotFoundException {
        Properties resultProps = new Properties();
        if (!RESULT_FILE.exists()) {
            RESULT_FILE.createNewFile();
        }
        FileInputStream fin = null;
        try {
            fin = new FileInputStream(RESULT_FILE);
            resultProps.load(fin);
            resultProps.put(oomTest.testMethod,
                            Integer.toString(oomTest.failedTests));
        } finally {
            if (fin != null) {
                fin.close();
            }
        }
        System.out.println("DEBUG: Finished running test '"
                           + oomTest.testMethod + "'.");
        if (LAST_TEST.equals(oomTest.testMethod)) {
            System.out.println("DEBUG: Determining overall test status.");
            Set<String> actualTestsRun = new HashSet<String>();
            int totalTests = ALL_TESTS.length;
            int failedTests = 0;
            for (Object key: resultProps.keySet()) {
                actualTestsRun.add((String)key);
                Object propVal = resultProps.get(key);
                int value = Integer.parseInt((String)propVal);
                failedTests += value;
            }
            if (!ALL_TESTS_SET.equals(actualTestsRun)) {
                String errorMsg = "Test failed! Expected to run tests '"
                        + ALL_TESTS_SET + "', but only these were run '"
                        + actualTestsRun + "'";
                throw new RuntimeException(errorMsg);
            }
            if (failedTests >= 3) {
                String errorMsg = "Test failed. Expected < 3 sub-tests to fail "
                                  + "for a pass. Got " + failedTests
                                  + " failed tests out of " + totalTests + ".";
                throw new RuntimeException(errorMsg);
            }
            RESULT_FILE.delete();
            System.out.println("All " + totalTests + " tests passed.");
        } else {
            System.out.println("DEBUG: More tests to run. Coninuing.");
            FileOutputStream fout = null;
            try {
                fout = new FileOutputStream(RESULT_FILE);
                resultProps.store(fout, "Storing results after test "
                                         + oomTest.testMethod);
            } finally {
                if (fout != null) {
                    fout.close();
                }
            }
        }
    }

    public static void main(String[] args) throws Exception {
        System.setProperty("test.vm.opts""-Xmx40m"); // Set debuggee VM option
        OomDebugTest oomTest = new OomDebugTest(args);
        try {
            oomTest.startTests();
        } catch (Throwable e) {
            System.out.println("DEBUG: Got exception for test run. " + e);
            e.printStackTrace();
            oomTest.failure();
        }
        determineOverallTestStatus(oomTest);
    }

}

¤ Dauer der Verarbeitung: 0.16 Sekunden  (vorverarbeitet)  ¤





Download des
Quellennavigators
Download des
sprechenden Kalenders

in der Quellcodebibliothek suchen




Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.


Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.


Bot Zugriff