23
23
24
24
/**
25
25
* @test
26
- * @bug 8167108 8266130 8282704
27
- * @summary Stress test java.lang.Thread.stop() at thread exit.
26
+ * @bug 8167108 8266130 8282704 8283467
27
+ * @summary Stress test JVM/TI StopThread() at thread exit.
28
+ * @requires vm.jvmti
28
29
* @modules java.base/java.lang:open
29
- * @run main/othervm StopAtExit
30
+ * @run main/othervm/native -agentlib:StopAtExit StopAtExit
30
31
*/
31
32
32
33
import java .lang .reflect .Method ;
36
37
public class StopAtExit extends Thread {
37
38
private final static int DEF_TIME_MAX = 30 ; // default max # secs to test
38
39
private final static String PROG_NAME = "StopAtExit" ;
40
+ private final static int JVMTI_ERROR_THREAD_NOT_ALIVE = 15 ;
39
41
40
42
public CountDownLatch exitSyncObj = new CountDownLatch (1 );
41
43
public CountDownLatch startSyncObj = new CountDownLatch (1 );
42
44
45
+ native static int stopThread (StopAtExit thr , Throwable exception );
46
+
43
47
public StopAtExit (ThreadGroup group , Runnable target ) {
44
48
super (group , target );
45
49
}
@@ -56,9 +60,9 @@ public void run() {
56
60
throw new RuntimeException ("Unexpected: " + e );
57
61
}
58
62
} catch (ThreadDeath td ) {
59
- // ignore because we're testing Thread.stop () which throws it
63
+ // ignore because we're testing JVM/TI StopThread () which throws it
60
64
} catch (NoClassDefFoundError ncdfe ) {
61
- // ignore because we're testing Thread.stop () which can cause it
65
+ // ignore because we're testing JVM/TI StopThread () which can cause it
62
66
}
63
67
}
64
68
@@ -89,27 +93,40 @@ public static void main(String[] args) {
89
93
// the thread is terminated.
90
94
ThreadGroup myTG = new ThreadGroup ("myTG-" + count );
91
95
myTG .setDaemon (true );
96
+ Throwable myException = new ThreadDeath ();
97
+ int retCode ;
92
98
StopAtExit thread = new StopAtExit (myTG , null );
93
99
thread .start ();
94
100
try {
95
101
// Wait for the worker thread to get going.
96
102
thread .startSyncObj .await ();
97
103
// Tell the worker thread to race to the exit and the
98
- // Thread.stop () calls will come in during thread exit.
104
+ // JVM/TI StopThread () calls will come in during thread exit.
99
105
thread .exitSyncObj .countDown ();
100
106
while (true ) {
101
- thread .stop ();
107
+ retCode = stopThread (thread , myException );
108
+
109
+ if (retCode == JVMTI_ERROR_THREAD_NOT_ALIVE ) {
110
+ // Done with JVM/TI StopThread() calls since
111
+ // thread is not alive.
112
+ break ;
113
+ } else if (retCode != 0 ) {
114
+ throw new RuntimeException ("thread " + thread .getName ()
115
+ + ": stopThread() " +
116
+ "retCode=" + retCode +
117
+ ": unexpected value." );
118
+ }
102
119
103
120
if (!thread .isAlive ()) {
104
- // Done with Thread.stop () calls since
121
+ // Done with JVM/TI StopThread () calls since
105
122
// thread is not alive.
106
123
break ;
107
124
}
108
125
}
109
126
} catch (InterruptedException e ) {
110
127
throw new Error ("Unexpected: " + e );
111
128
} catch (NoClassDefFoundError ncdfe ) {
112
- // Ignore because we're testing Thread.stop () which can
129
+ // Ignore because we're testing JVM/TI StopThread () which can
113
130
// cause it. Yes, a NoClassDefFoundError that happens
114
131
// in a worker thread can subsequently be seen in the
115
132
// main thread.
@@ -120,9 +137,18 @@ public static void main(String[] args) {
120
137
} catch (InterruptedException e ) {
121
138
throw new Error ("Unexpected: " + e );
122
139
}
123
- // This stop() call happens after the join() so it should do
124
- // nothing, but let's make sure.
125
- thread .stop ();
140
+ // This JVM/TI StopThread() happens after the join() so it
141
+ // should do nothing, but let's make sure.
142
+ retCode = stopThread (thread , myException );
143
+
144
+ if (retCode != JVMTI_ERROR_THREAD_NOT_ALIVE ) {
145
+ throw new RuntimeException ("thread " + thread .getName ()
146
+ + ": stopThread() " +
147
+ "retCode=" + retCode +
148
+ ": unexpected value; " +
149
+ "expected JVMTI_ERROR_THREAD_NOT_ALIVE(" +
150
+ JVMTI_ERROR_THREAD_NOT_ALIVE + ")." );
151
+ }
126
152
127
153
if (myTG .activeCount () != 0 ) {
128
154
// If the ThreadGroup still has a count, then the thread
0 commit comments