Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/java/lang/StackWalker/VerifyStackTrace.java
41149 views
1
/*
2
* Copyright (c) 2015, 2018, 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
import java.lang.reflect.InvocationTargetException;
25
import java.security.AccessController;
26
import java.security.PrivilegedAction;
27
import java.util.EnumSet;
28
import java.util.concurrent.atomic.AtomicLong;
29
import java.lang.StackWalker.StackFrame;
30
import java.lang.invoke.MethodHandle;
31
import java.lang.invoke.MethodHandles;
32
import java.lang.invoke.MethodType;
33
import java.util.Objects;
34
35
import static java.lang.StackWalker.Option.*;
36
37
/**
38
* @test
39
* @bug 8140450 8197901
40
* @summary Verify stack trace information obtained with respect to StackWalker
41
* options, when the stack contains lambdas, method handle invoke
42
* virtual calls, and reflection.
43
* @run main/othervm VerifyStackTrace
44
* @run main/othervm/java.security.policy=stackwalk.policy VerifyStackTrace
45
* @author danielfuchs
46
*/
47
public class VerifyStackTrace {
48
49
static interface TestCase {
50
StackWalker walker();
51
String description();
52
String expected();
53
}
54
static final class TestCase1 implements TestCase {
55
private final StackWalker walker = StackWalker.getInstance(RETAIN_CLASS_REFERENCE);
56
57
private final String description = "StackWalker.getInstance(" +
58
"StackWalker.Option.RETAIN_CLASS_REFERENCE)";
59
60
// Note: line numbers and lambda hashes will be erased when
61
// comparing stack traces. However, the stack may change
62
// if some methods are being renamed in the code base.
63
// If the JDKcode base changes and the test fails because of that,
64
// then after validating that the actual stack trace obtained
65
// is indeed correct (no frames are skipped that shouldn't)
66
// then you can cut & paste the <-- actual --> stack printed in the
67
// test output in here:
68
private final String expected =
69
"1: VerifyStackTrace.lambda$test$1(VerifyStackTrace.java:209)\n" +
70
"2: VerifyStackTrace$Handle.execute(VerifyStackTrace.java:145)\n" +
71
"3: VerifyStackTrace$Handle.run(VerifyStackTrace.java:158)\n" +
72
"4: VerifyStackTrace.invoke(VerifyStackTrace.java:188)\n" +
73
"5: VerifyStackTrace$1.run(VerifyStackTrace.java:218)\n" +
74
"6: java.base/java.security.AccessController.doPrivileged(AccessController.java:310)\n" +
75
"7: VerifyStackTrace.test(VerifyStackTrace.java:227)\n" +
76
"8: VerifyStackTrace.main(VerifyStackTrace.java:182)\n";
77
78
@Override public StackWalker walker() { return walker;}
79
@Override public String description() { return description;}
80
@Override public String expected() { return expected;}
81
}
82
static final class TestCase2 implements TestCase {
83
private final StackWalker walker = StackWalker.getInstance(
84
EnumSet.of(RETAIN_CLASS_REFERENCE, SHOW_REFLECT_FRAMES));
85
86
private final String description = "nStackWalker.getInstance(" +
87
"StackWalker.Option.RETAIN_CLASS_REFERENCE, " +
88
"StackWalker.Option.SHOW_REFLECT_FRAMES)";
89
90
// Note: line numbers and lambda hashes will be erased when
91
// comparing stack traces. However, the stack may change
92
// if some methods are being renamed in the code base.
93
// If the JDK code base changes and the test fails because of that,
94
// then after validating that the actual stack trace obtained
95
// is indeed correct (no frames are skipped that shouldn't)
96
// then you can cut & paste the <-- actual --> stack printed in the
97
// test output in here (don't forget the final \n):
98
private final String expected =
99
"1: VerifyStackTrace.lambda$test$1(VerifyStackTrace.java:211)\n" +
100
"2: VerifyStackTrace$Handle.execute(VerifyStackTrace.java:147)\n" +
101
"3: VerifyStackTrace$Handle.run(VerifyStackTrace.java:160)\n" +
102
"4: VerifyStackTrace.invoke(VerifyStackTrace.java:190)\n" +
103
"5: java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n" +
104
"6: java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\n" +
105
"7: java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n" +
106
"8: java.base/java.lang.reflect.Method.invoke(Method.java:520)\n" +
107
"9: VerifyStackTrace$1.run(VerifyStackTrace.java:220)\n" +
108
"10: java.base/java.security.AccessController.doPrivileged(AccessController.java:310)\n" +
109
"11: VerifyStackTrace.test(VerifyStackTrace.java:229)\n" +
110
"12: VerifyStackTrace.main(VerifyStackTrace.java:185)\n";
111
112
@Override public StackWalker walker() { return walker;}
113
@Override public String description() { return description;}
114
@Override public String expected() { return expected;}
115
}
116
static class TestCase3 implements TestCase {
117
private final StackWalker walker = StackWalker.getInstance(
118
EnumSet.of(RETAIN_CLASS_REFERENCE, SHOW_HIDDEN_FRAMES));
119
120
private final String description = "StackWalker.getInstance(" +
121
"StackWalker.Option.RETAIN_CLASS_REFERENCE, " +
122
"StackWalker.Option.SHOW_HIDDEN_FRAMES)";
123
124
// Note: line numbers and lambda hashes will be erased when
125
// comparing stack traces. However, the stack may change
126
// if some methods are being renamed in the code base.
127
// If the JDK code base changes and the test fails because of that,
128
// then after validating that the actual stack trace obtained
129
// is indeed correct (no frames are skipped that shouldn't)
130
// then you can cut & paste the <-- actual --> stack printed in the
131
// test output in here (don't forget the final \n):
132
private final String expected =
133
"1: VerifyStackTrace.lambda$test$1(VerifyStackTrace.java:213)\n" +
134
"2: VerifyStackTrace$$Lambda$1/0x00000007c0089430.run(Unknown Source)\n" +
135
"3: VerifyStackTrace$Handle.execute(VerifyStackTrace.java:149)\n" +
136
"4: java.base/java.lang.invoke.LambdaForm$DMH/0x00000007c008a830.invokeVirtual_LL_V(LambdaForm$DMH)\n" +
137
"5: java.base/java.lang.invoke.LambdaForm$MH/0x00000007c008a830.invoke_MT(LambdaForm$MH)\n" +
138
"6: VerifyStackTrace$Handle.run(VerifyStackTrace.java:162)\n" +
139
"7: VerifyStackTrace.invoke(VerifyStackTrace.java:192)\n" +
140
"8: java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n" +
141
"9: java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\n" +
142
"10: java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n" +
143
"11: java.base/java.lang.reflect.Method.invoke(Method.java:520)\n" +
144
"12: VerifyStackTrace$1.run(VerifyStackTrace.java:222)\n" +
145
"13: java.base/java.security.AccessController.executePrivileged(AccessController.java:759)\n" +
146
"14: java.base/java.security.AccessController.doPrivileged(AccessController.java:310)\n" +
147
"15: VerifyStackTrace.test(VerifyStackTrace.java:231)\n" +
148
"16: VerifyStackTrace.main(VerifyStackTrace.java:188)\n";
149
150
@Override public StackWalker walker() { return walker;}
151
@Override public String description() { return description;}
152
@Override public String expected() { return expected;}
153
}
154
155
static final class TestCase4 extends TestCase3 {
156
private final StackWalker walker = StackWalker.getInstance(
157
EnumSet.allOf(StackWalker.Option.class));
158
159
private final String description = "StackWalker.getInstance(" +
160
"StackWalker.Option.RETAIN_CLASS_REFERENCE, " +
161
"StackWalker.Option.SHOW_HIDDEN_FRAMES, " +
162
"StackWalker.Option.SHOW_REFLECT_FRAMES)";
163
164
@Override public StackWalker walker() {return walker;}
165
@Override public String description() {return description;}
166
}
167
168
public static class Handle implements Runnable {
169
170
Runnable impl;
171
public Handle(Runnable run) {
172
this.impl = run;
173
}
174
175
public void execute(Runnable run) {
176
run.run();
177
}
178
179
public void run() {
180
MethodHandles.Lookup lookup = MethodHandles.lookup();
181
MethodHandle handle = null;
182
try {
183
handle = lookup.findVirtual(Handle.class, "execute",
184
MethodType.methodType(void.class, Runnable.class));
185
} catch(NoSuchMethodException | IllegalAccessException x) {
186
throw new RuntimeException(x);
187
}
188
try {
189
handle.invoke(this, impl);
190
} catch(Error | RuntimeException x) {
191
throw x;
192
} catch(Throwable t) {
193
throw new RuntimeException(t);
194
}
195
}
196
}
197
198
static String prepare(String produced, boolean eraseSensitiveInfo) {
199
if (eraseSensitiveInfo) {
200
// Erase sensitive information before comparing:
201
// comparing line numbers is too fragile, so we just erase them
202
// out before comparing. We also erase the hash-like names of
203
// synthetic frames introduced by lambdas & method handles
204
return produced.replaceAll(":[1-9][0-9]*\\)", ":00)")
205
.replaceAll("/0x[0-9a-f]+\\.run", "/xxxxxxxx.run")
206
.replaceAll("/0x[0-9a-f]+\\.invoke", "/xxxxxxxx.invoke")
207
// LFs may or may not be pre-generated, making frames differ
208
.replaceAll("DirectMethodHandle\\$Holder", "LambdaForm\\$DMH")
209
.replaceAll("Invokers\\$Holder", "LambdaForm\\$MH")
210
.replaceAll("MH\\.invoke", "MH/xxxxxxxx.invoke")
211
// invoke frames may or may not have basic method type
212
// information encoded for diagnostic purposes
213
.replaceAll("xx\\.invoke([A-Za-z]*)_[A-Z_]+", "xx.invoke$1")
214
.replaceAll("\\$[0-9]+", "\\$??");
215
} else {
216
return produced;
217
}
218
}
219
220
221
public static void main(String[] args) {
222
test(new TestCase1());
223
test(new TestCase2());
224
test(new TestCase3());
225
test(new TestCase4());
226
}
227
228
public static void invoke(Runnable run) {
229
run.run();
230
}
231
232
static final class Recorder {
233
boolean found; // stop recording after main
234
public void recordSTE(long counter, StringBuilder s, StackFrame f) {
235
if (found) return;
236
found = VerifyStackTrace.class.equals(f.getDeclaringClass()) &&
237
"main".equals(f.getMethodName());
238
String line = String.format("%d: %s", counter, f.toStackTraceElement());
239
s.append(line).append('\n');
240
System.out.println(line);
241
}
242
}
243
244
245
static void test(TestCase test) {
246
System.out.println("\nTesting: " + test.description());
247
final AtomicLong counter = new AtomicLong();
248
final StringBuilder builder = new StringBuilder();
249
final Recorder recorder = new Recorder();
250
final Runnable run = () -> test.walker().forEach(
251
f -> recorder.recordSTE(counter.incrementAndGet(), builder, f));
252
final Handle handle = new Handle(run);
253
254
// We're not using lambda on purpose here. We want the anonymous
255
// class on the stack.
256
PrivilegedAction<Object> pa = new PrivilegedAction<Object>() {
257
@Override
258
public Object run() {
259
try {
260
return VerifyStackTrace.class
261
.getMethod("invoke", Runnable.class)
262
.invoke(null, handle);
263
} catch (NoSuchMethodException
264
| IllegalAccessException
265
| InvocationTargetException ex) {
266
System.out.flush();
267
throw new RuntimeException(ex);
268
}
269
}
270
};
271
AccessController.doPrivileged(pa);
272
System.out.println("Main found: " + recorder.found);
273
if (!Objects.equals(prepare(test.expected(), true), prepare(builder.toString(), true))) {
274
System.out.flush();
275
try {
276
// sleep to make it less likely that System.out & System.err will
277
// interleave.
278
Thread.sleep(1000);
279
} catch (InterruptedException ex) {
280
}
281
System.err.println("\nUnexpected stack trace: "
282
+ "\n<!-- expected -->\n"
283
+ prepare(test.expected(), true)
284
+ "\n<-- actual -->\n"
285
+ prepare(builder.toString(), false));
286
throw new RuntimeException("Unexpected stack trace for: " + test.description());
287
}
288
}
289
290
291
}
292
293