Skip to content

Commit

Permalink
added libgraal.CrashAtIsFatal option
Browse files Browse the repository at this point in the history
  • Loading branch information
dougxc committed Jun 23, 2020
1 parent 18ed3b9 commit 72c40b9
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -188,17 +188,28 @@ private static void checkForRequestedCrash(StructuredGraph graph) {
}
}
if (crashLabel != null) {
String crashMessage = "Forced crash after compiling " + crashLabel;
notifyCrash(crashMessage);
if (permanentBailout) {
throw new PermanentBailoutException("Forced crash after compiling " + crashLabel);
throw new PermanentBailoutException(crashMessage);
}
if (bailout) {
throw new RetryableBailoutException("Forced crash after compiling " + crashLabel);
throw new RetryableBailoutException(crashMessage);
}
throw new RuntimeException("Forced crash after compiling " + crashLabel);
throw new RuntimeException(crashMessage);
}
}
}

/**
* Substituted by {@code com.oracle.svm.graal.hotspot.libgraal.
* Target_org_graalvm_compiler_core_GraalCompiler} to optionally test routing fatal error
* handling from libgraal to HotSpot.
*/
@SuppressWarnings("unused")
private static void notifyCrash(String crashMessage) {
}

/**
* Builds the graph, optimizes it.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ public void fatalError() {
}
}

public CFunctionPointer getFatalErrorFunctionPointer() {
return fatalErrorFunctionPointer;
}

interface LogFunctionPointer extends CFunctionPointer {
@InvokeCFunctionPointer
void invoke(CCharPointer bytes, UnsignedWord length);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins;
import org.graalvm.compiler.nodes.graphbuilderconf.MethodSubstitutionPlugin;
import org.graalvm.compiler.nodes.spi.SnippetParameterInfo;
import org.graalvm.compiler.options.Option;
import org.graalvm.compiler.options.OptionDescriptor;
import org.graalvm.compiler.options.OptionDescriptors;
import org.graalvm.compiler.options.OptionDescriptorsMap;
Expand All @@ -89,10 +90,14 @@
import org.graalvm.compiler.truffle.runtime.GraalTruffleRuntime;
import org.graalvm.libgraal.LibGraal;
import org.graalvm.nativeimage.ImageSingletons;
import org.graalvm.nativeimage.LogHandler;
import org.graalvm.nativeimage.VMRuntime;
import org.graalvm.nativeimage.c.type.CTypeConversion;
import org.graalvm.nativeimage.c.type.CTypeConversion.CCharPointerHolder;
import org.graalvm.nativeimage.hosted.Feature;
import org.graalvm.nativeimage.hosted.RuntimeReflection;
import org.graalvm.word.Pointer;
import org.graalvm.word.WordFactory;

import com.oracle.graal.pointsto.flow.InvokeTypeFlow;
import com.oracle.graal.pointsto.meta.AnalysisMethod;
Expand All @@ -108,7 +113,9 @@
import com.oracle.svm.core.graal.meta.RuntimeConfiguration;
import com.oracle.svm.core.graal.snippets.NodeLoweringProvider;
import com.oracle.svm.core.jni.JNIRuntimeAccess;
import com.oracle.svm.core.log.FunctionPointerLogHandler;
import com.oracle.svm.core.option.HostedOptionKey;
import com.oracle.svm.core.option.RuntimeOptionKey;
import com.oracle.svm.core.option.RuntimeOptionValues;
import com.oracle.svm.core.option.XOptions;
import com.oracle.svm.core.snippets.KnownIntrinsics;
Expand All @@ -135,6 +142,15 @@

public final class LibGraalFeature implements com.oracle.svm.core.graal.GraalFeature {

static class Options {
// @formatter:off
@Option(help = "Converts an exception triggered by the CrashAt option into a fatal error " +
"if a non-null pointer was passed in the _fatal option to JNI_CreateJavaVM. " +
"This option exists for the purpose of testing fatal error handling in libgraal.")
static final RuntimeOptionKey<Boolean> CrashAtIsFatal = new RuntimeOptionKey<>(false);
// @formatter:on
}

private HotSpotReplacementsImpl hotSpotSubstrateReplacements;

@Override
Expand Down Expand Up @@ -670,6 +686,28 @@ void afterRun() {
}
}

@TargetClass(className = "org.graalvm.compiler.core.GraalCompiler", onlyWith = LibGraalFeature.IsEnabled.class)
final class Target_org_graalvm_compiler_core_GraalCompiler {
@SuppressWarnings("unused")
@Substitute()
private static void notifyCrash(String crashMessage) {
if (LibGraalFeature.Options.CrashAtIsFatal.getValue()) {
LogHandler handler = ImageSingletons.lookup(LogHandler.class);
if (handler instanceof FunctionPointerLogHandler) {
FunctionPointerLogHandler fpHandler = (FunctionPointerLogHandler) handler;
if (fpHandler.getFatalErrorFunctionPointer().isNonNull()) {
try (CCharPointerHolder holder = CTypeConversion.toCString(crashMessage)) {
handler.log(holder.get(), WordFactory.unsigned(crashMessage.getBytes().length));
}
handler.fatalError();
}
}
// If changing this message, update the test for it in mx_vm_gate.py
System.out.println("CrashAtIsFatal: no fatalError function pointer installed");
}
}
}

@TargetClass(className = "org.graalvm.compiler.hotspot.SymbolicSnippetEncoder", onlyWith = LibGraalFeature.IsEnabled.class)
@Delete("shouldn't appear in libgraal")
final class Target_org_graalvm_compiler_hotspot_SymbolicSnippetEncoder {
Expand Down
41 changes: 39 additions & 2 deletions vm/mx.vm/mx_vm_gate.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
import re
from mx_gate import Task

from os import environ, listdir, remove
from os import environ, listdir, remove, linesep
from os.path import join, exists, dirname, isdir, isfile, getsize
from tempfile import NamedTemporaryFile, mkdtemp
from contextlib import contextmanager
Expand Down Expand Up @@ -85,7 +85,44 @@ def gate_body(args, tasks):
# run avrora on the GraalVM binary itself
with Task('LibGraal Compiler:GraalVM DaCapo-avrora', tasks, tags=[VmGateTasks.libgraal]) as t:
if t:
mx.run([join(mx_sdk_vm_impl.graalvm_home(), 'bin', 'java'), '-XX:+UseJVMCICompiler', '-XX:+UseJVMCINativeLibrary', '-jar', mx.library('DACAPO').get_path(True), 'avrora'])
java_exe = join(mx_sdk_vm_impl.graalvm_home(), 'bin', 'java')
mx.run([java_exe,
'-XX:+UseJVMCICompiler',
'-XX:+UseJVMCINativeLibrary',
'-jar', mx.library('DACAPO').get_path(True), 'avrora'])

# Ensure that fatal errors in libgraal route back to HotSpot
testdir = mkdtemp()
try:
cmd = [java_exe,
'-XX:+UseJVMCICompiler',
'-XX:+UseJVMCINativeLibrary',
'-Dlibgraal.CrashAt=length,hashCode',
'-Dlibgraal.CrashAtIsFatal=true',
'-jar', mx.library('DACAPO').get_path(True), 'avrora']
out = mx.OutputCapture()
exitcode = mx.run(cmd, cwd=testdir, nonZeroIsFatal=False, out=out)
if exitcode == 0:
if 'CrashAtIsFatal: no fatalError function pointer installed' in out.data:
# Executing a VM that does not configure fatal errors handling
# in libgraal to route back through the VM.
pass
else:
mx.abort('Expected following command to result in non-zero exit code: ' + ' '.join(cmd))
else:
hs_err = None
testdir_entries = listdir(testdir)
for name in testdir_entries:
if name.startswith('hs_err_pid'):
hs_err = join(testdir, name)
if hs_err is None:
mx.abort('Expected a file starting with "hs_err_pid" in test directory. Entries found=' + str(testdir_entries))
with open(join(testdir, hs_err)) as fp:
contents = fp.read()
if 'Fatal error in JVMCI' not in contents:
mx.abort('Expected "Fatal error in JVMCI" to be in contents of ' + hs_err + ':' + linesep + contents)
finally:
mx.rmtree(testdir)

with Task('LibGraal Compiler:CTW', tasks, tags=[VmGateTasks.libgraal]) as t:
if t:
Expand Down

0 comments on commit 72c40b9

Please sign in to comment.