Skip to content

Commit

Permalink
Logging refactoring.
Browse files Browse the repository at this point in the history
  • Loading branch information
cstancu committed Mar 26, 2018
1 parent ac78c6f commit 267d7f0
Show file tree
Hide file tree
Showing 16 changed files with 265 additions and 177 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright (c) 2018, 2018, 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 org.graalvm.nativeimage;

import org.graalvm.nativeimage.c.type.CCharPointer;
import org.graalvm.word.UnsignedWord;

/**
* Implement this interface to create a custom log handler. The custom log handler must be installed
* in the {@code ImageSingletons} at {@code Feature.duringSetup()} time like so:
*
* <pre>
* class LogHandlerFeature implements Feature {
* {@literal @}Override
* public void duringSetup(DuringSetupAccess access) {
* ImageSingletons.add(LogHandler.class, new CustomLogHandler());
* }
* }
* </pre>
*
* If no custom log handler is installed a default one would be provided at
* {@code Feature.beforeAnalysis()} time. Installing a custom log handler at a later time, after the
* default one has been installed, will result in an error.
*
*/
public interface LogHandler {

static LogHandler get() {
return ImageSingletons.lookup(LogHandler.class);
}

/** Writes the raw bytes. */
void log(CCharPointer bytes, UnsignedWord length);

/** Forces the log to flush to its destination. */
void flush();

/** Exit the VM. Method must not return. No Java code should be run after this point. */
void fatalError();
}
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,8 @@ public void afterRegistration(AfterRegistrationAccess access) {
@Override
@Uninterruptible(reason = "Called from uninterruptible code.")
public void close() {
final Log trace = Log.noopLog().string("[PinnedObject.close:").string(" this: ").object(this);
trace.string(" referent: ").object(referent);
assert open : "Should not call close() on a closed PinnedObject.";
open = false;
trace.string("]").newline();
}

/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -468,15 +468,12 @@ private static void pushToThreadLocalFreeList(AlignedHeader alignedChunk) {
*/
@Uninterruptible(reason = "Pops from the free list that is drained, at a safepoint, by garbage collections.")
private static AlignedHeader popFromThreadLocalFreeList() {
log().string("[ThreadLocalAllocation.popFromThreadLocalFreeList:").newline();
log().string(" before freeList: ").hex(freeList.get()).string("]").newline();
final AlignedHeader result = freeList.get();
if (result.isNonNull()) {
final AlignedHeader next = result.getNext();
result.setNext(WordFactory.nullPointer());
freeList.set(next);
}
log().string(" after freeList: ").hex(freeList.get()).string(" result: ").hex(result).string("]").newline();
return result;
}

Expand Down Expand Up @@ -569,8 +566,6 @@ private static void retireAllocationChunk(Descriptor tlab) {
if (allocationTop.isNonNull()) {
AlignedHeader alignedChunk = tlab.getAlignedChunk();

log().string(" [ThreadLocalAllocator.retireAllocationChunk: tlab ").hex(tlab).string(" chunk ").hex(alignedChunk).string(" top ").hex(allocationTop).string(" ]").newline();

assert alignedChunk.getTop().isNull();
assert alignedChunk.getEnd().equal(tlab.getAllocationEnd(END_IDENTITY));

Expand All @@ -595,8 +590,6 @@ static void resumeAllocationChunk(Descriptor tlab) {

AlignedHeader alignedChunk = tlab.getAlignedChunk();
if (alignedChunk.isNonNull()) {
log().string(" [ThreadLocalAllocator.resumeAllocationChunk: tlab ").hex(tlab).string(" chunk ").hex(alignedChunk).string(" top ").hex(alignedChunk.getTop()).string(" ]").newline();

tlab.setAllocationTop(alignedChunk.getTop(), TOP_IDENTITY);
tlab.setAllocationEnd(alignedChunk.getEnd(), END_IDENTITY);
alignedChunk.setTop(WordFactory.nullPointer());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,7 @@ protected static UnsignedWord getChunkSizeForObject(UnsignedWord objectSize) {
*/
@Uninterruptible(reason = "Returns uninitialized memory.", callerMustBe = true)
public static Pointer allocateMemory(UnalignedHeader that, UnsignedWord size) {
final Log trace = Log.noopLog().string("[UnalignedHeapChunk.allocateMemory:");
final UnsignedWord available = availableObjectMemory(that);
trace.string(" size").unsigned(size).string(" top: ").hex(that.getTop()).string(" end: ").hex(that.getEnd()).string(" available: ").unsigned(available).newline();
// Is memory available for the requested size?
Pointer result = WordFactory.nullPointer();
if (size.belowOrEqual(available)) {
Expand All @@ -161,7 +159,6 @@ public static Pointer allocateMemory(UnalignedHeader that, UnsignedWord size) {
final Pointer newTop = result.add(size);
setTopCarefully(that, newTop);
}
trace.string(" returns: ").hex(result).string("]").newline();
return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
import org.graalvm.nativeimage.ImageSingletons;
import org.graalvm.nativeimage.Isolate;
import org.graalvm.nativeimage.IsolateThread;
import org.graalvm.nativeimage.LogHandler;
import org.graalvm.nativeimage.StackValue;
import org.graalvm.nativeimage.c.function.CEntryPointContext;
import org.graalvm.nativeimage.c.function.CFunction;
Expand Down Expand Up @@ -364,7 +365,7 @@ private static int reportException(Throwable exception) {
}
}
Log.log().newline();
LibC.abort();
LogHandler.get().fatalError();
return Errors.UNSPECIFIED; // unreachable
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Copyright (c) 2018, 2018, 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.
*
* 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.posix;

import java.io.FileDescriptor;

import com.oracle.svm.core.annotate.AutomaticFeature;
import org.graalvm.nativeimage.Feature;
import org.graalvm.nativeimage.ImageSingletons;
import org.graalvm.nativeimage.LogHandler;
import org.graalvm.nativeimage.c.type.CCharPointer;
import org.graalvm.word.UnsignedWord;

import com.oracle.svm.core.config.ConfigurationValues;

@AutomaticFeature
class DefaultLogHandlerFeature implements Feature {
@Override
public void beforeAnalysis(BeforeAnalysisAccess access) {
/* An alternative log handler can be set in Feature.duringSetup(). */
if (!ImageSingletons.contains(LogHandler.class)) {
/*
* Install the default log handler in ImageSingletons such that if another feature tries
* to install another log handler at a later point it will get an error.
*/
LogHandler logHandler = new DefaultLogHandler();
ImageSingletons.add(LogHandler.class, logHandler);
}
}
}

public class DefaultLogHandler implements LogHandler {

@Override
public void log(CCharPointer bytes, UnsignedWord length) {
if (!ConfigurationValues.getOSInterface().writeBytesUninterruptibly(getOutputFile(), bytes, length)) {
/*
* We are in a low-level log routine and output failed, so there is little we can do.
*/
ConfigurationValues.getOSInterface().abort();
}
}

@Override
public void flush() {
ConfigurationValues.getOSInterface().flush(getOutputFile());
/* ignore error -- they're benign */
}

@Override
public void fatalError() {
ConfigurationValues.getOSInterface().abort();
}

/* Allow subclasses to customize the file descriptor that we write to. */
private static FileDescriptor getOutputFile() {
return FileDescriptor.err;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.graalvm.compiler.options.Option;
import org.graalvm.compiler.word.Word;
import org.graalvm.nativeimage.Feature;
import org.graalvm.nativeimage.LogHandler;
import org.graalvm.nativeimage.Platform;
import org.graalvm.nativeimage.Platforms;
import org.graalvm.nativeimage.StackValue;
Expand Down Expand Up @@ -120,7 +121,7 @@ private static void dispatch(int signalNumber, @SuppressWarnings("unused") sigin
log.string("Use runtime option -R:-InstallSegfaultHandler if you don't want to use SubstrateSegfaultHandler.").newline();

log.newline().string("Bye bye ...").newline().newline();
LibC.abort();
LogHandler.get().fatalError();
}

/** The address of the signal handler for signals handled by Java code, above. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.graalvm.compiler.word.Word;
import org.graalvm.nativeimage.Feature;
import org.graalvm.nativeimage.ImageSingletons;
import org.graalvm.nativeimage.LogHandler;
import org.graalvm.nativeimage.Platform;
import org.graalvm.nativeimage.Platforms;
import org.graalvm.nativeimage.StackValue;
Expand All @@ -44,9 +45,9 @@
import com.oracle.svm.core.locks.VMMutex;
import com.oracle.svm.core.log.Log;
import com.oracle.svm.core.posix.headers.Errno;
import com.oracle.svm.core.posix.headers.LibC;
import com.oracle.svm.core.posix.headers.Pthread;
import com.oracle.svm.core.posix.headers.Time;
import com.oracle.svm.core.thread.VMThreads;

import jdk.vm.ci.meta.JavaKind;

Expand Down Expand Up @@ -140,15 +141,16 @@ public static void initialize() {
}
}

@Uninterruptible(reason = "Called from uninterruptible code.")
@Uninterruptible(reason = "Called from uninterruptible code.", calleeMustBe = false)
protected static void checkResult(int result, String functionName) {
if (result != 0) {
/*
* Functions are called very early and late during our execution, so there is not much
* we can do when they fail.
*/
VMThreads.StatusSupport.setStatusIgnoreSafepoints();
Log.log().string(functionName).string(" returned ").signed(result).newline();
LibC.abort();
LogHandler.get().fatalError();
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,6 @@ public interface Thunk {
* Prints extensive diagnostic information to the given Log.
*/
@RestrictHeapAccess(access = RestrictHeapAccess.Access.NO_ALLOCATION, reason = "Must not allocate during printing diagnostics.")
@Uninterruptible(reason = "Allow printDiagnostics to be used in uninterruptible code.", calleeMustBe = false)
public static void printDiagnostics(Log log, Pointer sp, CodePointer ip) {
if (diagnosticsInProgress) {
log.string("Error: printDiagnostics already in progress.").newline();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
import java.lang.annotation.Target;

/**
* Methods annotated with this annotation have restricted access to the heap.
* Methods annotated with this annotation have restricted access to the heap. This annotation is
* checked transitively, i.e., callees of the annotated method do not need to be annotated.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@
*/
package com.oracle.svm.core.jdk;

import org.graalvm.nativeimage.LogHandler;

import com.oracle.svm.core.SubstrateUtil;
import com.oracle.svm.core.annotate.NeverInline;
import com.oracle.svm.core.annotate.Substitute;
import com.oracle.svm.core.annotate.TargetClass;
import com.oracle.svm.core.annotate.Uninterruptible;
import com.oracle.svm.core.config.ConfigurationValues;
import com.oracle.svm.core.log.Log;
import com.oracle.svm.core.snippets.KnownIntrinsics;
import com.oracle.svm.core.stack.ThreadStackPrinter;
Expand All @@ -45,25 +46,17 @@ final class Target_com_oracle_svm_core_util_VMError {
@Substitute
private static RuntimeException shouldNotReachHere() {
ThreadStackPrinter.printBacktrace();
Log log = Log.log();
log.autoflush(true);
log.string("VMError.shouldNotReachHere").newline();
VMThreads.StatusSupport.setStatusIgnoreSafepoints();
SubstrateUtil.printDiagnostics(log, KnownIntrinsics.readCallerStackPointer(), KnownIntrinsics.readReturnAddress());
ConfigurationValues.getOSInterface().abort();
VMErrorSubstitutions.shutdown();
return null;
}

@Uninterruptible(reason = "Allow VMError to be used in uninterruptible code.")
@Substitute
private static RuntimeException shouldNotReachHere(String msg) {
ThreadStackPrinter.printBacktrace();
Log log = Log.log();
log.autoflush(true);
log.string("VMError.shouldNotReachHere: ").string(msg).newline();
VMThreads.StatusSupport.setStatusIgnoreSafepoints();
SubstrateUtil.printDiagnostics(log, KnownIntrinsics.readCallerStackPointer(), KnownIntrinsics.readReturnAddress());
ConfigurationValues.getOSInterface().abort();
VMErrorSubstitutions.shutdown(msg);
return null;
}

Expand All @@ -76,13 +69,9 @@ private static RuntimeException shouldNotReachHere(Throwable ex) {
* Throwable. So we access the raw detailMessage directly from the field in Throwable. That
* is better than printing nothing.
*/
Log log = Log.log();
log.autoflush(true);
String detailMessage = JDKUtils.getRawMessage(ex);
log.string("VMError.shouldNotReachHere: ").string(ex.getClass().getName()).string(": ").string(detailMessage).newline();
VMThreads.StatusSupport.setStatusIgnoreSafepoints();
SubstrateUtil.printDiagnostics(log, KnownIntrinsics.readCallerStackPointer(), KnownIntrinsics.readReturnAddress());
ConfigurationValues.getOSInterface().abort();
VMErrorSubstitutions.shutdown(detailMessage, ex.getClass().getName());
return null;
}

Expand Down Expand Up @@ -116,4 +105,34 @@ private static RuntimeException unsupportedFeature(String msg) {

/** Dummy class to have a class with the file's name. */
public class VMErrorSubstitutions {

@Uninterruptible(reason = "Allow use in uninterruptible code.", calleeMustBe = false)
static void shutdown() {
Log log = Log.log();
log.autoflush(true);
log.string("VMError.shouldNotReachHere").newline();
doShutdown(log);
}

@Uninterruptible(reason = "Allow use in uninterruptible code.", calleeMustBe = false)
static void shutdown(String msg) {
Log log = Log.log();
log.autoflush(true);
log.string("VMError.shouldNotReachHere: ").string(msg).newline();
doShutdown(log);
}

@Uninterruptible(reason = "Allow use in uninterruptible code.", calleeMustBe = false)
static void shutdown(String detailMessage, String exceptionClassName) {
Log log = Log.log();
log.autoflush(true);
log.string("VMError.shouldNotReachHere: ").string(exceptionClassName).string(": ").string(detailMessage).newline();
doShutdown(log);
}

@Uninterruptible(reason = "Allow use in uninterruptible code.", calleeMustBe = false)
private static void doShutdown(Log log) {
SubstrateUtil.printDiagnostics(log, KnownIntrinsics.readCallerStackPointer(), KnownIntrinsics.readReturnAddress());
LogHandler.get().fatalError();
}
}
Loading

0 comments on commit 267d7f0

Please sign in to comment.