Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import java.util.ListIterator;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
Expand Down Expand Up @@ -167,6 +168,7 @@
import com.oracle.svm.core.option.RuntimeOptionValues;
import com.oracle.svm.core.option.SubstrateOptionsParser;
import com.oracle.svm.core.snippets.SnippetRuntime;
import com.oracle.svm.core.util.ExitStatus;
import com.oracle.svm.core.util.InterruptImageBuilding;
import com.oracle.svm.core.util.LayeredHostedImageHeapMapCollector;
import com.oracle.svm.core.util.LayeredImageHeapMapStore;
Expand Down Expand Up @@ -568,7 +570,7 @@ protected void doRun(Map<Method, CEntryPointData> entryPoints, JavaMainSupport j

try (DebugContext debug = new Builder(options, new GraalDebugHandlersFactory(GraalAccess.getOriginalSnippetReflection())).build();
DebugCloseable featureCleanup = () -> featureHandler.forEachFeature(Feature::cleanup)) {
setupNativeImage(options, entryPoints, javaMainSupport, harnessSubstitutions, debug);
setupNativeImage(options, entryPoints, javaMainSupport, imageName, harnessSubstitutions, debug);

boolean returnAfterAnalysis = runPointsToAnalysis(imageName, options, debug);
if (returnAfterAnalysis) {
Expand Down Expand Up @@ -923,9 +925,10 @@ protected boolean verifyAssignableTypes() {

@SuppressWarnings("try")
protected void setupNativeImage(OptionValues options, Map<Method, CEntryPointData> entryPoints, JavaMainSupport javaMainSupport,
SubstitutionProcessor harnessSubstitutions, DebugContext debug) {
String imageName, SubstitutionProcessor harnessSubstitutions, DebugContext debug) {
try (Indent ignored = debug.logAndIndent("setup native-image builder")) {
try (StopTimer ignored1 = TimerCollection.createTimerAndStart(TimerCollection.Registry.SETUP)) {
installDefaultExceptionHandler(options, imageName);
SubstrateTargetDescription target = createTarget();
ImageSingletons.add(Platform.class, loader.platform);
ImageSingletons.add(SubstrateTargetDescription.class, target);
Expand Down Expand Up @@ -1121,6 +1124,30 @@ protected void setupNativeImage(OptionValues options, Map<Method, CEntryPointDat
}
}

/**
* We install a default uncaught exception handler to make sure that the image build terminates
* if an uncaught exception is encountered on <b>any</b> thread. As an unexpectedly failing
* thread could theoretically cause a deadlock if another thread was waiting for its result, we
* preventively terminate the build via {@link System#exit}.
*/
private void installDefaultExceptionHandler(OptionValues options, String imageName) {
/*
* A flag to make sure we run the reporting only once even if multiple uncaught exceptions
* are encountered.
*/
var reportStarted = new AtomicBoolean();
Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> {
if (reportStarted.compareAndSet(false, true)) {
/*
* Call into the ProgressReporter to provide error reporting as if the throwable was
* thrown on the main thread.
*/
reporter.printEpilog(Optional.of(imageName), Optional.of(NativeImageGenerator.this), loader, NativeImageGeneratorRunner.BuildOutcome.FAILED, Optional.of(throwable), options);
System.exit(ExitStatus.BUILDER_ERROR.getValue());
}
});
}

protected void registerEntryPointStubs(Map<Method, CEntryPointData> entryPoints) {
entryPoints.forEach((method, entryPointData) -> CEntryPointCallStubSupport.singleton().registerStubForMethod(method, () -> entryPointData));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,7 @@ private static void reportStackTrace(PrintWriter pw, Throwable t) {
pw.println("## Stack Trace");
pw.println();
pw.println("```java");
Throwable current = t;
while (current != null) {
t.printStackTrace(pw);
current = current.getCause();
if (current != null) {
pw.println("Caused by:");
}
}
t.printStackTrace(pw);
pw.println("```");
}

Expand Down
Loading