8287982: Concurrent implicit attach from native threads crashes VM

Reviewed-by: dholmes, rehn
This commit is contained in:
Alan Bateman 2022-06-22 07:48:14 +00:00
parent 9e2d9ac59a
commit 7cf71bc2d3
7 changed files with 382 additions and 39 deletions

View file

@ -652,35 +652,39 @@ public class Thread implements Runnable {
@SuppressWarnings("removal")
Thread(ThreadGroup g, String name, int characteristics, Runnable task,
long stackSize, AccessControlContext acc) {
if (name == null) {
throw new InternalError("name cannot be null");
}
Thread parent = currentThread();
boolean attached = (parent == this); // primordial or JNI attached
if (attached && g == null) {
throw new InternalError("group cannot be null when attaching");
}
SecurityManager security = System.getSecurityManager();
if (g == null) {
// the security manager can choose the thread group
if (security != null) {
g = security.getThreadGroup();
}
// default to current thread's group
if (attached) {
if (g == null) {
g = parent.getThreadGroup();
throw new InternalError("group cannot be null when attaching");
}
}
this.holder = new FieldHolder(g, task, stackSize, NORM_PRIORITY, false);
} else {
SecurityManager sm = System.getSecurityManager();
if (g == null) {
// the security manager can choose the thread group
if (sm != null) {
g = sm.getThreadGroup();
}
// permission checks when creating a child Thread
if (!attached && security != null) {
security.checkAccess(g);
if (isCCLOverridden(getClass())) {
security.checkPermission(SecurityConstants.SUBCLASS_IMPLEMENTATION_PERMISSION);
// default to current thread's group
if (g == null) {
g = parent.getThreadGroup();
}
}
// permission checks when creating a child Thread
if (sm != null) {
sm.checkAccess(g);
if (isCCLOverridden(getClass())) {
sm.checkPermission(SecurityConstants.SUBCLASS_IMPLEMENTATION_PERMISSION);
}
}
int priority = Math.min(parent.getPriority(), g.getMaxPriority());
this.holder = new FieldHolder(g, task, stackSize, priority, parent.isDaemon());
}
if (attached && VM.initLevel() < 1) {
@ -688,7 +692,8 @@ public class Thread implements Runnable {
} else {
this.tid = ThreadIdentifiers.next();
}
this.name = name;
this.name = (name != null) ? name : genThreadName();
if (acc != null) {
this.inheritedAccessControlContext = acc;
} else {
@ -720,18 +725,6 @@ public class Thread implements Runnable {
this.contextClassLoader = ClassLoader.getSystemClassLoader();
}
}
int priority;
boolean daemon;
if (attached) {
// primordial or attached thread
priority = NORM_PRIORITY;
daemon = false;
} else {
priority = Math.min(parent.getPriority(), g.getMaxPriority());
daemon = parent.isDaemon();
}
this.holder = new FieldHolder(g, task, stackSize, priority, daemon);
}
/**
@ -1153,7 +1146,7 @@ public class Thread implements Runnable {
* @see <a href="#inheritance">Inheritance when creating threads</a>
*/
public Thread() {
this(null, genThreadName(), 0, null, 0, null);
this(null, null, 0, null, 0, null);
}
/**
@ -1174,7 +1167,7 @@ public class Thread implements Runnable {
* @see <a href="#inheritance">Inheritance when creating threads</a>
*/
public Thread(Runnable task) {
this(null, genThreadName(), 0, task, 0, null);
this(null, null, 0, task, 0, null);
}
/**
@ -1183,7 +1176,7 @@ public class Thread implements Runnable {
* This is not a public constructor.
*/
Thread(Runnable task, @SuppressWarnings("removal") AccessControlContext acc) {
this(null, genThreadName(), 0, task, 0, acc);
this(null, null, 0, task, 0, acc);
}
/**
@ -1216,7 +1209,7 @@ public class Thread implements Runnable {
* @see <a href="#inheritance">Inheritance when creating threads</a>
*/
public Thread(ThreadGroup group, Runnable task) {
this(group, genThreadName(), 0, task, 0, null);
this(group, null, 0, task, 0, null);
}
/**