Skip to content

Commit

Permalink
Refactor SubstrateSegfaultHandler
Browse files Browse the repository at this point in the history
  • Loading branch information
pejovica committed Apr 14, 2020
1 parent b47aaf4 commit 2e6156b
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@
*/
package com.oracle.svm.core.posix;

import org.graalvm.compiler.options.Option;
import org.graalvm.nativeimage.ImageInfo;
import org.graalvm.nativeimage.ImageSingletons;
import org.graalvm.nativeimage.Isolate;
import org.graalvm.nativeimage.IsolateThread;
Expand All @@ -42,6 +40,7 @@

import com.oracle.svm.core.Isolates;
import com.oracle.svm.core.SubstrateOptions;
import com.oracle.svm.core.SubstrateSegfaultHandler;
import com.oracle.svm.core.annotate.AutomaticFeature;
import com.oracle.svm.core.annotate.RestrictHeapAccess;
import com.oracle.svm.core.annotate.Uninterruptible;
Expand All @@ -56,9 +55,7 @@
import com.oracle.svm.core.graal.nodes.WriteCurrentVMThreadNode;
import com.oracle.svm.core.graal.nodes.WriteHeapBaseNode;
import com.oracle.svm.core.graal.snippets.CEntryPointSnippets.IsolateCreationWatcher;
import com.oracle.svm.core.jdk.RuntimeSupport;
import com.oracle.svm.core.log.Log;
import com.oracle.svm.core.option.RuntimeOptionKey;
import com.oracle.svm.core.posix.headers.LibC;
import com.oracle.svm.core.posix.headers.Signal;
import com.oracle.svm.core.posix.headers.Signal.AdvancedSignalDispatcher;
Expand All @@ -69,27 +66,17 @@
import com.oracle.svm.core.thread.VMThreads;

@AutomaticFeature
public class SegfaultHandlerFeature implements Feature {

class PosixSubstrateSegfaultHandlerFeature implements Feature {
@Override
public void afterRegistration(AfterRegistrationAccess access) {
ImageSingletons.add(SubstrateSegfaultHandler.class, new PosixSubstrateSegfaultHandler());
if (SubstrateOptions.useLLVMBackend()) {
ImageSingletons.add(IsolateCreationWatcher.class, new SubstrateSegfaultHandler.SingleIsolateSegfaultIsolateSetup());
ImageSingletons.add(IsolateCreationWatcher.class, new PosixSubstrateSegfaultHandler.SingleIsolateSegfaultIsolateSetup());
}
}

@Override
public void beforeAnalysis(BeforeAnalysisAccess access) {
RuntimeSupport.getRuntimeSupport().addStartupHook(SubstrateSegfaultHandler::install);
}
}

class SubstrateSegfaultHandler {

public static class Options {
@Option(help = "Install segfault handler that prints register contents and full Java stacktrace. Default: enabled for an executable, disabled for a shared library.")//
static final RuntimeOptionKey<Boolean> InstallSegfaultHandler = new RuntimeOptionKey<>(null);
}
class PosixSubstrateSegfaultHandler extends SubstrateSegfaultHandler {

private static volatile boolean dispatchInProgress = false;

Expand Down Expand Up @@ -148,20 +135,18 @@ private static void dump(int signalNumber, ucontext_t uContext) {
}

/** The address of the signal handler for signals handled by Java code, above. */
private static final CEntryPointLiteral<AdvancedSignalDispatcher> advancedSignalDispatcher = CEntryPointLiteral.create(SubstrateSegfaultHandler.class, "dispatch", int.class, siginfo_t.class,
ucontext_t.class);
private static final CEntryPointLiteral<AdvancedSignalDispatcher> advancedSignalDispatcher = CEntryPointLiteral.create(PosixSubstrateSegfaultHandler.class,
"dispatch", int.class, siginfo_t.class, ucontext_t.class);

static void install() {
Boolean optionValue = Options.InstallSegfaultHandler.getValue();
if (optionValue == Boolean.TRUE || (optionValue == null && ImageInfo.isExecutable())) {
int structSigActionSize = SizeOf.get(sigaction.class);
sigaction structSigAction = StackValue.get(structSigActionSize);
LibC.memset(structSigAction, WordFactory.signed(0), WordFactory.unsigned(structSigActionSize));
/* Register sa_sigaction signal handler */
structSigAction.sa_flags(Signal.SA_SIGINFO());
structSigAction.sa_sigaction(advancedSignalDispatcher.getFunctionPointer());
Signal.sigaction(Signal.SignalEnum.SIGSEGV, structSigAction, WordFactory.nullPointer());
}
@Override
protected void install() {
int structSigActionSize = SizeOf.get(sigaction.class);
sigaction structSigAction = StackValue.get(structSigActionSize);
LibC.memset(structSigAction, WordFactory.signed(0), WordFactory.unsigned(structSigActionSize));
/* Register sa_sigaction signal handler */
structSigAction.sa_flags(Signal.SA_SIGINFO());
structSigAction.sa_sigaction(advancedSignalDispatcher.getFunctionPointer());
Signal.sigaction(Signal.SignalEnum.SIGSEGV, structSigAction, WordFactory.nullPointer());
}

static class SingleIsolateSegfaultIsolateSetup implements IsolateCreationWatcher {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright (c) 2020, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.oracle.svm.core;

import org.graalvm.compiler.options.Option;
import org.graalvm.nativeimage.ImageInfo;
import org.graalvm.nativeimage.ImageSingletons;
import org.graalvm.nativeimage.hosted.Feature;

import com.oracle.svm.core.annotate.AutomaticFeature;
import com.oracle.svm.core.jdk.RuntimeSupport;
import com.oracle.svm.core.option.RuntimeOptionKey;

@AutomaticFeature
class SubstrateSegfaultHandlerFeature implements Feature {
@Override
public void beforeAnalysis(Feature.BeforeAnalysisAccess access) {
if (!ImageSingletons.contains(SubstrateSegfaultHandler.class)) {
return; /* No segfault handler. */
}
RuntimeSupport.getRuntimeSupport().addStartupHook(SubstrateSegfaultHandler::startupHook);
}
}

public abstract class SubstrateSegfaultHandler {

public static class Options {
@Option(help = "Install segfault handler that prints register contents and full Java stacktrace. Default: enabled for an executable, disabled for a shared library.")//
static final RuntimeOptionKey<Boolean> InstallSegfaultHandler = new RuntimeOptionKey<>(null);
}

static void startupHook() {
Boolean optionValue = Options.InstallSegfaultHandler.getValue();
if (optionValue == Boolean.TRUE || (optionValue == null && ImageInfo.isExecutable())) {
ImageSingletons.lookup(SubstrateSegfaultHandler.class).install();
}
}

/** Installs the platform dependent segfault handler. */
protected abstract void install();
}

0 comments on commit 2e6156b

Please sign in to comment.