1 /*
2  * Copyright (c) 2016, 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  * @bug 8150778
27  * @summary Test exception depths, and code to get stack traces
28  * @modules java.base/jdk.internal.misc:open
29  * @modules java.base/java.lang:open
30  * @library /test/lib
31  * @run main/othervm -XX:MaxJavaStackTraceDepth=1024 TestThrowable
32  */
33 
34 import java.lang.reflect.Field;
35 import jdk.test.lib.Asserts;
36 
37 public class TestThrowable {
38 
39   // Inner class that throws a lot of exceptions
40   static class Thrower {
41     static int MaxJavaStackTraceDepth = 1024; // as above
42     int[] depths = {10, 34, 100, 1023, 1024, 1025};
43     int count = 0;
44 
getDepth(Throwable t)45     int getDepth(Throwable t) throws Exception {
46       Field f = Throwable.class.getDeclaredField("depth");
47       f.setAccessible(true); // it's private
48       return f.getInt(t);
49     }
50 
callThrow(int depth)51     void callThrow(int depth) {
52       if (++count < depth) {
53         callThrow(depth);
54       } else {
55         throw new RuntimeException("depth tested " + depth);
56       }
57     }
testThrow()58     void testThrow() throws Exception {
59       for (int d : depths) {
60         try {
61           count = getDepth(new Throwable());
62           callThrow(d);
63         } catch(Exception e) {
64           e.getStackTrace();
65           System.out.println(e.getMessage());
66           int throwableDepth = getDepth(e);
67           Asserts.assertTrue(throwableDepth == d ||
68                      (d > MaxJavaStackTraceDepth && throwableDepth == MaxJavaStackTraceDepth),
69                      "depth should return the correct value: depth tested=" +
70                      d + " throwableDepth=" + throwableDepth);
71         }
72       }
73     }
74   }
75 
main(String... unused)76   public static void main(String... unused) throws Exception {
77     Thrower t = new Thrower();
78     t.testThrow();
79   }
80 }
81