1 /*
 2  * Copyright (c) 2022, 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 /*
26  * @bug 8320515
27  * @summary This test checks that ObjectMonitors with dead objects don't
28  *          cause asserts, crashes, or failures when various sub-systems
29  *          in the JVM find them.
30  * @library /testlibrary /test/lib
31  * @modules jdk.management
32  */
33 
34 /*
35  * @requires os.family != "windows" & os.family != "aix"
36  * @test id=DetachThread
37  * @run main/othervm/native MonitorWithDeadObjectTest 0
38  */
39 
40 /*
41  * @requires os.family != "windows" & os.family != "aix"
42  * @test id=DumpThreadsBeforeDetach
43  * @run main/othervm/native MonitorWithDeadObjectTest 1
44  */
45 
46 /*
47  * @requires os.family != "windows" & os.family != "aix"
48  * @test id=DumpThreadsAfterDetach
49  * @run main/othervm/native MonitorWithDeadObjectTest 2
50  */
51 
52 import java.lang.management.ManagementFactory;
53 import java.lang.management.ThreadMXBean;
54 
55 public class MonitorWithDeadObjectTest {
56     public static native void createMonitorWithDeadObject();
57     public static native void createMonitorWithDeadObjectDumpThreadsBeforeDetach();
58 
59     static {
60         System.loadLibrary("MonitorWithDeadObjectTest");
61     }
62 
63     private static void dumpThreadsWithLockedMonitors() {
64         ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
65         threadBean.dumpAllThreads(true, false);
66     }
67 
68     private static void testDetachThread() {
69         // Create an ObjectMonitor with a dead object from an attached thread.
70         // This used to provoke an assert in DetachCurrentThread.
71         createMonitorWithDeadObject();
72     }
73 
74     private static void testDumpThreadsBeforeDetach() {
75         // Create an ObjectMonitor with a dead object from an attached thread
76         // and perform a thread dump before detaching the thread.
77         createMonitorWithDeadObjectDumpThreadsBeforeDetach();
78     }
79 
80     private static void testDumpThreadsAfterDetach() {
81         createMonitorWithDeadObject();
82 
83         // The thread dumping code used to not tolerate monitors with dead
84         // objects and the detach code used to not unlock these monitors, so
85         // test that we don't end up with a bug where these monitors are not
86         // unlocked and then passed to the thread dumping code.
87         dumpThreadsWithLockedMonitors();
88     }
89 
90     public static void main(String[] args) throws Exception {
91         int test = Integer.parseInt(args[0]);
92         switch (test) {
93             case 0: testDetachThread(); break;
94             case 1: testDumpThreadsBeforeDetach(); break;
95             case 2: testDumpThreadsAfterDetach(); break;
96             default: throw new RuntimeException("Unknown test");
97         };
98     }
99 }