jdk

Форк
0
/
UniqueVtableTest.java 
200 строк · 7.2 Кб
1
/*
2
 * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
 *
5
 * This code is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU General Public License version 2 only, as
7
 * published by the Free Software Foundation.
8
 *
9
 * This code is distributed in the hope that it will be useful, but WITHOUT
10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12
 * version 2 for more details (a copy is included in the LICENSE file that
13
 * accompanied this code).
14
 *
15
 * You should have received a copy of the GNU General Public License version
16
 * 2 along with this work; if not, write to the Free Software Foundation,
17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
 *
19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
 * or visit www.oracle.com if you need additional information or have any
21
 * questions.
22
 */
23

24
/**
25
 * @test
26
 *
27
 * @library /test/lib
28
 * @requires vm.hasSA
29
 * @modules jdk.hotspot.agent/sun.jvm.hotspot
30
 *          jdk.hotspot.agent/sun.jvm.hotspot.debugger
31
 *          jdk.hotspot.agent/sun.jvm.hotspot.types
32
 *          jdk.hotspot.agent/sun.jvm.hotspot.types.basic
33
 *
34
 * @run driver UniqueVtableTest
35
 */
36

37
import java.util.ArrayList;
38
import java.util.Iterator;
39
import java.util.HashMap;
40
import java.util.List;
41
import java.util.Map;
42

43
import sun.jvm.hotspot.HotSpotAgent;
44
import sun.jvm.hotspot.debugger.Address;
45
import sun.jvm.hotspot.types.Type;
46
import sun.jvm.hotspot.types.basic.BasicTypeDataBase;
47

48
import jdk.test.lib.apps.LingeredApp;
49
import jdk.test.lib.process.ProcessTools;
50
import jdk.test.lib.process.OutputAnalyzer;
51
import jdk.test.lib.SA.SATestUtils;
52

53

54
public class UniqueVtableTest {
55

56
    private static String type2String(Type t) {
57
        return t + " (extends " + t.getSuperclass() + ")";
58
    }
59

60
    private static void log(Object o) {
61
        System.out.println(o);
62
    }
63

64
    private static void runTest(long pid) throws Throwable {
65
        HotSpotAgent agent = new HotSpotAgent();
66
        log("Attaching to process ID " + pid + "...");
67
        agent.attach((int) pid);
68
        log("Attached successfully.");
69

70
        Throwable reasonToFail = null;
71

72
        try {
73
            runTest(agent);
74
        } catch (Throwable ex) {
75
            reasonToFail = ex;
76
        } finally {
77
            try {
78
                agent.detach();
79
            } catch (Exception ex) {
80
                log("detach error:");
81
                ex.printStackTrace(System.out);
82
                // do not override original error
83
                if (reasonToFail != null) {
84
                    reasonToFail = ex;
85
                }
86
            }
87
        }
88
        if (reasonToFail != null) {
89
            throw reasonToFail;
90
        }
91
    }
92

93
    private static void runTest(HotSpotAgent agent) throws Throwable {
94
        Map<Address, List<Type>> vtableToTypesMap = new HashMap<>();
95
        Iterator<Type> it = agent.getTypeDataBase().getTypes();
96
        int dupsFound = 0;
97
        // TypeDataBase knows nothing about vtables,
98
        // but actually agent.getTypeDataBase() returns HotSpotTypeDataBase (extends BasicTypeDataBase)
99
        // and BasicTypeDataBase has a method to get vtable for Types.
100
        BasicTypeDataBase typeDB = (BasicTypeDataBase)(agent.getTypeDataBase());
101
        int total = 0;
102
        int vm_classes_with_vtable = 0;
103
        int vm_classes_without_vtable = 0;
104
        while (it.hasNext()) {
105
            total++;
106
            Type t = it.next();
107
            Address vtable = typeDB.vtblForType(t);
108
            if (vtable != null) {
109
                vm_classes_with_vtable++;
110
                List<Type> typeList = vtableToTypesMap.get(vtable);
111
                if (typeList == null) {
112
                    vtableToTypesMap.put(vtable, new ArrayList<>(List.of(t)));
113
                } else {
114
                    // duplicate found
115
                    dupsFound++;
116
                    typeList.add(t);
117
                }
118
            }
119

120
            // IntegerType/StringType/JavaPrimitiveType/OopType/PointerType types
121
            // are expected to have no vtable.
122
            // Log classes which might need vtable.
123
            if (vtable == null
124
                    && !t.isCIntegerType()
125
                    && !t.isCStringType()
126
                    && !t.isJavaPrimitiveType()
127
                    && !t.isOopType()
128
                    && !t.isPointerType()) {
129
                vm_classes_without_vtable++;
130
                log("vtable is null for " + type2String(t));
131
            }
132
        }
133
        log("total: " + total
134
            + ", vm_classes_with_vtable: " + vm_classes_with_vtable
135
            + ", vm_classes_without_vtable: " + vm_classes_without_vtable);
136
        if (dupsFound > 0) {
137
            vtableToTypesMap.forEach((vtable, list) -> {
138
                if (list.size() > 1) {
139
                    log("Duplicate vtable: " + vtable + ": ");
140
                    list.forEach(t -> log("  - " + type2String(t)));
141
                }
142
            });
143
            throw new RuntimeException("Duplicate vtable(s) found: " + dupsFound);
144
        }
145
    }
146

147
    private static void createAnotherToAttach(long lingeredAppPid) throws Throwable {
148
        // Start a new process to attach to the lingered app
149
        ProcessBuilder processBuilder = ProcessTools.createLimitedTestJavaProcessBuilder(
150
            "--add-modules=jdk.hotspot.agent",
151
            "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot=ALL-UNNAMED",
152
            "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.debugger=ALL-UNNAMED",
153
            "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.types=ALL-UNNAMED",
154
            "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.types.basic=ALL-UNNAMED",
155
            "UniqueVtableTest",
156
            Long.toString(lingeredAppPid));
157
        SATestUtils.addPrivilegesIfNeeded(processBuilder);
158
        OutputAnalyzer output = ProcessTools.executeProcess(processBuilder);
159
        output.shouldHaveExitValue(0);
160
        System.out.println(output.getOutput());
161
    }
162

163
    private static void runMain() throws Throwable {
164
        Throwable reasonToFail = null;
165
        LingeredApp app = null;
166
        try {
167
            app = LingeredApp.startApp();
168
            createAnotherToAttach(app.getPid());
169
        } catch (Throwable ex) {
170
            reasonToFail = ex;
171
        } finally {
172
            try {
173
                LingeredApp.stopApp(app);
174
            } catch (Exception ex) {
175
                log("LingeredApp.stopApp error:");
176
                ex.printStackTrace(System.out);
177
                // do not override original error
178
                if (reasonToFail != null) {
179
                    reasonToFail = ex;
180
                }
181
            }
182
        }
183
        if (reasonToFail != null) {
184
            throw reasonToFail;
185
        }
186
    }
187

188
    public static void main(String... args) throws Throwable {
189
        SATestUtils.skipIfCannotAttach(); // throws SkippedException if attach not expected to work.
190

191
        if (args == null || args.length == 0) {
192
            // Main test process.
193
            runMain();
194
        } else {
195
            // Sub-process to attach, arg[0] is the target process pid.
196
            runTest(Long.parseLong(args[0]));
197
        }
198
    }
199

200
 }
201

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.