Skip to content

Commit 33bbd8b

Browse files
[GR-59422] Avoid sun_nio_ch_NativeThread pthread_kill on sulong
`pthread_self` returns a "virtual" pthread_t value on sulong but `pthread_kill` is not intrinsified, leading to crashes.
1 parent 3467dc0 commit 33bbd8b

File tree

5 files changed

+123
-8
lines changed

5 files changed

+123
-8
lines changed

espresso/src/com.oracle.truffle.espresso.classfile/src/com/oracle/truffle/espresso/classfile/descriptors/Symbol.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,11 @@ public static void ensureInitialized() {
453453
public static final Symbol<Name> SIG_IGN = StaticSymbols.putName("SIG_IGN");
454454
// sun.misc.NativeSignalHandler
455455
public static final Symbol<Name> handler = StaticSymbols.putName("handler");
456+
// sun.nio.ch.NativeThread
457+
public static final Symbol<Name> isNativeThread = StaticSymbols.putName("isNativeThread");
458+
public static final Symbol<Name> current0 = StaticSymbols.putName("current0");
459+
public static final Symbol<Name> signal = StaticSymbols.putName("signal");
460+
public static final Symbol<Name> init = StaticSymbols.putName("init");
456461

457462
// jdk.internal.util.ArraysSupport
458463
public static final Symbol<Name> vectorizedMismatch = StaticSymbols.putName("vectorizedMismatch");
@@ -688,6 +693,7 @@ public static void ensureInitialized() {
688693
public static final Symbol<Type> java_nio_file_Path = StaticSymbols.putType("Ljava/nio/file/Path;");
689694
public static final Symbol<Type> java_nio_file_Path_array = StaticSymbols.putType("[Ljava/nio/file/Path;");
690695
public static final Symbol<Type> java_nio_file_Paths = StaticSymbols.putType("Ljava/nio/file/Paths;");
696+
public static final Symbol<Type> sun_nio_ch_NativeThread = StaticSymbols.putType("Lsun/nio/ch/NativeThread;");
691697

692698
public static final Symbol<Type> jdk_internal_loader_ClassLoaders = StaticSymbols.putType("Ljdk/internal/loader/ClassLoaders;");
693699
public static final Symbol<Type> jdk_internal_loader_ClassLoaders$PlatformClassLoader = StaticSymbols.putType("Ljdk/internal/loader/ClassLoaders$PlatformClassLoader;");
@@ -1131,6 +1137,7 @@ public static void ensureInitialized() {
11311137
public static final Symbol<Signature> _void_long_long = StaticSymbols.putSignature(Type._void, Type._long, Type._long);
11321138
public static final Symbol<Signature> _boolean_int = StaticSymbols.putSignature(Type._boolean, Type._int);
11331139
public static final Symbol<Signature> _boolean_int_int = StaticSymbols.putSignature(Type._boolean, Type._int, Type._int);
1140+
public static final Symbol<Signature> _boolean_long = StaticSymbols.putSignature(Type._boolean, Type._long);
11341141
public static final Symbol<Signature> _int_int_int = StaticSymbols.putSignature(Type._int, Type._int, Type._int);
11351142
public static final Symbol<Signature> _void_char_array = StaticSymbols.putSignature(Type._void, Type._char_array);
11361143
public static final Symbol<Signature> _void_byte_array = StaticSymbols.putSignature(Type._void, Type._byte_array);

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/ffi/NativeAccess.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@
3535
import com.oracle.truffle.api.interop.UnsupportedMessageException;
3636
import com.oracle.truffle.api.interop.UnsupportedTypeException;
3737
import com.oracle.truffle.espresso.EspressoOptions;
38-
import com.oracle.truffle.espresso.meta.EspressoError;
3938
import com.oracle.truffle.espresso.classfile.JavaKind;
39+
import com.oracle.truffle.espresso.meta.EspressoError;
4040
import com.oracle.truffle.espresso.runtime.EspressoProperties;
4141

4242
/**

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/meta/Meta.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,18 @@ public Meta(EspressoContext context) {
378378
java_nio_file_Paths = knownKlass(Type.java_nio_file_Paths);
379379
java_nio_file_Paths_get = java_nio_file_Paths.requireDeclaredMethod(Name.get, Signature.Path_String_String_array);
380380

381+
ObjectKlass nioNativeThreadKlass = knownKlass(Type.sun_nio_ch_NativeThread);
382+
sun_nio_ch_NativeThread_init = nioNativeThreadKlass.lookupDeclaredMethod(Name.init, Signature._void);
383+
if (getJavaVersion().java21OrLater()) {
384+
sun_nio_ch_NativeThread_isNativeThread = nioNativeThreadKlass.requireDeclaredMethod(Name.isNativeThread, Signature._boolean_long);
385+
sun_nio_ch_NativeThread_current0 = nioNativeThreadKlass.requireDeclaredMethod(Name.current0, Signature._long);
386+
sun_nio_ch_NativeThread_signal = null;
387+
} else {
388+
sun_nio_ch_NativeThread_isNativeThread = null;
389+
sun_nio_ch_NativeThread_current0 = null;
390+
sun_nio_ch_NativeThread_signal = nioNativeThreadKlass.requireDeclaredMethod(Name.signal, Signature._void_long);
391+
}
392+
381393
sun_launcher_LauncherHelper = knownKlass(Type.sun_launcher_LauncherHelper);
382394
sun_launcher_LauncherHelper_printHelpMessage = sun_launcher_LauncherHelper.requireDeclaredMethod(Name.printHelpMessage, Signature._void_boolean);
383395
sun_launcher_LauncherHelper_ostream = sun_launcher_LauncherHelper.requireDeclaredField(Name.ostream, Type.java_io_PrintStream);
@@ -1554,6 +1566,11 @@ private DiffVersionLoadHelper diff() {
15541566
public final ObjectKlass java_nio_file_Paths;
15551567
public final Method java_nio_file_Paths_get;
15561568

1569+
public final Method sun_nio_ch_NativeThread_isNativeThread;
1570+
public final Method sun_nio_ch_NativeThread_current0;
1571+
public final Method sun_nio_ch_NativeThread_signal;
1572+
public final Method sun_nio_ch_NativeThread_init;
1573+
15571574
// Array support.
15581575
public final ObjectKlass java_lang_Cloneable;
15591576
public final ObjectKlass java_io_Serializable;

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/substitutions/Target_sun_nio_ch_NativeThread.java

Lines changed: 74 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,82 @@
2222
*/
2323
package com.oracle.truffle.espresso.substitutions;
2424

25-
/**
26-
* This substitution is only needed when using the Sulong backend, since installing signal handlers
27-
* is not supported. See GR-29359.
28-
*/
25+
import com.oracle.truffle.api.dsl.Bind;
26+
import com.oracle.truffle.api.dsl.Cached;
27+
import com.oracle.truffle.api.dsl.Specialization;
28+
import com.oracle.truffle.api.nodes.DirectCallNode;
29+
import com.oracle.truffle.espresso.EspressoOptions;
30+
import com.oracle.truffle.espresso.ffi.nfi.NFISulongNativeAccess;
31+
import com.oracle.truffle.espresso.runtime.EspressoContext;
32+
import com.oracle.truffle.espresso.substitutions.VersionFilter.Java17OrEarlier;
33+
import com.oracle.truffle.espresso.substitutions.VersionFilter.Java21OrLater;
34+
2935
@EspressoSubstitutions
3036
public final class Target_sun_nio_ch_NativeThread {
31-
37+
/*
38+
* This doesn't exist on Windows, it just won't match
39+
*/
3240
@Substitution
33-
public static void init() {
34-
// nop
41+
abstract static class Init extends SubstitutionNode {
42+
abstract void execute();
43+
44+
@Specialization
45+
static void doDefault(@Bind("getContext()") EspressoContext context,
46+
@Cached("create(context.getMeta().sun_nio_ch_NativeThread_init.getCallTargetNoSubstitution())") DirectCallNode original) {
47+
// avoid the installation of a signal handler except on SVM and not with llvm
48+
if (EspressoOptions.RUNNING_ON_SVM && !(context.getNativeAccess() instanceof NFISulongNativeAccess)) {
49+
original.call();
50+
}
51+
}
52+
}
53+
54+
@Substitution(versionFilter = Java21OrLater.class)
55+
abstract static class IsNativeThread extends SubstitutionNode {
56+
abstract boolean execute(long tid);
57+
58+
@Specialization
59+
static boolean doDefault(long tid,
60+
@Bind("getContext()") EspressoContext context,
61+
@Cached("create(context.getMeta().sun_nio_ch_NativeThread_isNativeThread.getCallTargetNoSubstitution())") DirectCallNode original) {
62+
if (context.getNativeAccess() instanceof NFISulongNativeAccess) {
63+
// sulong virtualizes pthread_self but not ptrhead_kill
64+
// signal to the JDK that we don't support signaling
65+
return false;
66+
} else {
67+
return (boolean) original.call(tid);
68+
}
69+
}
70+
}
71+
72+
@Substitution(versionFilter = Java21OrLater.class)
73+
abstract static class Current0 extends SubstitutionNode {
74+
abstract long execute();
75+
76+
@Specialization
77+
static long doDefault(@Bind("getContext()") EspressoContext context,
78+
@Cached("create(context.getMeta().sun_nio_ch_NativeThread_current0.getCallTargetNoSubstitution())") DirectCallNode original) {
79+
if (context.getNativeAccess() instanceof NFISulongNativeAccess) {
80+
// sulong virtualizes pthread_self but not ptrhead_kill
81+
// signal to the JDK that we don't support signaling
82+
return 0;
83+
} else {
84+
return (long) original.call();
85+
}
86+
}
87+
}
88+
89+
@Substitution(versionFilter = Java17OrEarlier.class)
90+
abstract static class Signal extends SubstitutionNode {
91+
abstract void execute(long nt);
92+
93+
@Specialization
94+
static void doDefault(long nt,
95+
@Bind("getContext()") EspressoContext context,
96+
@Cached("create(context.getMeta().sun_nio_ch_NativeThread_signal.getCallTargetNoSubstitution())") DirectCallNode original) {
97+
// sulong virtualizes pthread_self but not ptrhead_kill
98+
if (!(context.getNativeAccess() instanceof NFISulongNativeAccess)) {
99+
original.call(nt);
100+
}
101+
}
35102
}
36103
}

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/substitutions/VersionFilter.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,18 @@ public boolean isValidFor(JavaVersion version) {
8989
}
9090
}
9191

92+
final class Java17OrEarlier implements VersionFilter {
93+
public static final Java17OrEarlier INSTANCE = new Java17OrEarlier();
94+
95+
private Java17OrEarlier() {
96+
}
97+
98+
@Override
99+
public boolean isValidFor(JavaVersion version) {
100+
return version.java17OrEarlier();
101+
}
102+
}
103+
92104
final class Java18OrEarlier implements VersionFilter {
93105
public static final Java18OrEarlier INSTANCE = new Java18OrEarlier();
94106

@@ -124,4 +136,16 @@ public boolean isValidFor(JavaVersion version) {
124136
return version.java20OrLater();
125137
}
126138
}
139+
140+
final class Java21OrLater implements VersionFilter {
141+
public static final Java21OrLater INSTANCE = new Java21OrLater();
142+
143+
private Java21OrLater() {
144+
}
145+
146+
@Override
147+
public boolean isValidFor(JavaVersion version) {
148+
return version.java21OrLater();
149+
}
150+
}
127151
}

0 commit comments

Comments
 (0)