Skip to content

Commit

Permalink
Transplant recent LoadService fixes from master.
Browse files Browse the repository at this point in the history
* Fix autoload in the presence of canonicalized paths
* Fix require locking in the presence of canonicalized paths
* Fix circular require warning setting $!
  • Loading branch information
headius committed Apr 20, 2015
1 parent c384fd0 commit 1735752
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 118 deletions.
24 changes: 15 additions & 9 deletions core/src/main/java/org/jruby/runtime/ThreadContext.java
Expand Up @@ -48,14 +48,12 @@
import org.jruby.ext.fiber.ThreadFiber;
import org.jruby.internal.runtime.methods.DynamicMethod;
import org.jruby.lexer.yacc.ISourcePosition;
import org.jruby.ext.fiber.ThreadFiber;
import org.jruby.parser.StaticScope;
import org.jruby.runtime.backtrace.BacktraceData;
import org.jruby.runtime.backtrace.TraceType;
import org.jruby.runtime.backtrace.TraceType.Gather;
import org.jruby.runtime.backtrace.BacktraceElement;
import org.jruby.runtime.backtrace.RubyStackTraceElement;
import org.jruby.runtime.backtrace.TraceType;
import org.jruby.runtime.backtrace.TraceType.Gather;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.runtime.profile.ProfileCollection;
import org.jruby.runtime.scope.ManyVarsDynamicScope;
Expand Down Expand Up @@ -766,12 +764,19 @@ public IRubyObject setConstantInObject(String internedName, IRubyObject result)

return result;
}

private static void addBackTraceElement(Ruby runtime, RubyArray backtrace, RubyStackTraceElement element) {
RubyString str = RubyString.newString(runtime, element.mriStyleString());
backtrace.append(str);

/**
* Render the current backtrace as a string to the given StringBuilder. This will honor the currently-configured
* backtrace format and content.
*
* @param sb the StringBuilder to which to render the backtrace
*/
public void renderCurrentBacktrace(StringBuilder sb) {
TraceType traceType = runtime.getInstanceConfig().getTraceType();
BacktraceData backtraceData = traceType.getBacktrace(this, false);
traceType.getFormat().renderBacktrace(backtraceData.getBacktrace(runtime), sb, false);
}

/**
* Create an Array with backtrace information for Kernel#caller
* @param runtime
Expand Down Expand Up @@ -799,7 +804,8 @@ public IRubyObject createCallerBacktrace(int level, Integer length, StackTraceEl
RubyArray newTrace = runtime.newArray(trace.length);

for (int i = level; i - level < trace.length; i++) {
addBackTraceElement(runtime, newTrace, trace[i - level]);
RubyString str = RubyString.newString(runtime, trace[i - level].mriStyleString());
newTrace.append(str);
}

if (RubyInstanceConfig.LOG_CALLERS) TraceType.dumpCaller(newTrace);
Expand Down
83 changes: 59 additions & 24 deletions core/src/main/java/org/jruby/runtime/backtrace/TraceType.java
Expand Up @@ -28,6 +28,14 @@ public TraceType(Gather gather, Format format) {
this.format = format;
}

public Gather getGather() {
return gather;
}

public Format getFormat() {
return format;
}

/**
* Get a normal Ruby backtrace, using the current Gather type.
*
Expand Down Expand Up @@ -60,20 +68,20 @@ public static void logBacktrace(RubyStackTraceElement[] trace) {
LOG.info(" " + element.getFileName() + ":" + element.getLineNumber() + " in " + element.getMethodName());
}
}

public static void dumpException(RubyException exception) {
LOG.info("Exception raised: {} : {}", exception.getMetaClass(), exception);
}

public static void dumpBacktrace(RubyException exception) {
Ruby runtime = exception.getRuntime();
System.err.println("Backtrace generated:\n" + Format.JRUBY.printBacktrace(exception, runtime.getPosix().isatty(FileDescriptor.err)));
}

public static void dumpCaller(RubyArray trace) {
LOG.info("Caller backtrace generated:\n" + trace);
}

public static void dumpCaller(RubyStackTraceElement[] trace) {
LOG.info("Caller backtrace generated:\n" + Arrays.toString(trace));
}
Expand All @@ -86,13 +94,13 @@ public static TraceType traceTypeFor(String style) {
if (style.equalsIgnoreCase("raw")) return new TraceType(Gather.RAW, Format.JRUBY);
else if (style.equalsIgnoreCase("ruby_framed")) return new TraceType(Gather.NORMAL, Format.JRUBY);
else if (style.equalsIgnoreCase("normal")) return new TraceType(Gather.NORMAL, Format.JRUBY);
// deprecated, just uses jruby format now
// deprecated, just uses jruby format now
else if (style.equalsIgnoreCase("rubinius")) return new TraceType(Gather.NORMAL, Format.JRUBY);
else if (style.equalsIgnoreCase("full")) return new TraceType(Gather.FULL, Format.JRUBY);
else if (style.equalsIgnoreCase("mri")) return new TraceType(Gather.NORMAL, Format.MRI);
else return new TraceType(Gather.NORMAL, Format.JRUBY);
}

public enum Gather {
/**
* Full raw backtraces with all Java frames included.
Expand All @@ -113,7 +121,7 @@ public BacktraceData getBacktraceData(ThreadContext context, StackTraceElement[]
*/
FULL {
public BacktraceData getBacktraceData(ThreadContext context, StackTraceElement[] javaTrace, boolean nativeException) {
return new BacktraceData(
return new BacktraceData(
javaTrace,
context.createBacktrace2(0, nativeException),
true,
Expand Down Expand Up @@ -183,7 +191,7 @@ public BacktraceData getBacktraceData(ThreadContext context, boolean nativeExcep
/**
* Gather backtrace data for an integrated trace if the current gather type is "NORMAL", otherwise use the
* current gather type.
*
*
* @param context
* @param javaTrace
* @return
Expand All @@ -194,7 +202,7 @@ public BacktraceData getIntegratedBacktraceData(ThreadContext context, StackTrac
if (useGather == NORMAL) {
useGather = INTEGRATED;
}

BacktraceData data = useGather.getBacktraceData(context, javaTrace, false);

context.runtime.incrementBacktraceCount();
Expand All @@ -205,7 +213,7 @@ public BacktraceData getIntegratedBacktraceData(ThreadContext context, StackTrac

public abstract BacktraceData getBacktraceData(ThreadContext context, StackTraceElement[] javaTrace, boolean nativeException);
}

public enum Format {
/**
* Formatting like C Ruby
Expand All @@ -214,6 +222,10 @@ public enum Format {
public String printBacktrace(RubyException exception, boolean console) {
return printBacktraceMRI(exception, console);
}

public void renderBacktrace(RubyStackTraceElement[] elts, StringBuilder buffer, boolean color) {
renderBacktraceMRI(elts, buffer, color);
}
},

/**
Expand All @@ -223,9 +235,14 @@ public String printBacktrace(RubyException exception, boolean console) {
public String printBacktrace(RubyException exception, boolean console) {
return printBacktraceJRuby(exception, console);
}

public void renderBacktrace(RubyStackTraceElement[] elts, StringBuilder buffer, boolean color) {
renderBacktraceJRuby(elts, buffer, color);
}
};

public abstract String printBacktrace(RubyException exception, boolean console);
public abstract void renderBacktrace(RubyStackTraceElement[] elts, StringBuilder buffer, boolean color);
}

protected static String printBacktraceMRI(RubyException exception, boolean console) {
Expand Down Expand Up @@ -304,16 +321,9 @@ protected static String printBacktraceMRI(RubyException exception, boolean conso

protected static String printBacktraceJRuby(RubyException exception, boolean console) {
Ruby runtime = exception.getRuntime();
RubyStackTraceElement[] frames = exception.getBacktraceElements();
if (frames == null) frames = new RubyStackTraceElement[0];

// find longest method name
int longestMethod = 0;
for (RubyStackTraceElement frame : frames) {
longestMethod = Math.max(longestMethod, frame.getMethodName().length());
}

StringBuilder buffer = new StringBuilder();
boolean color = console && runtime.getInstanceConfig().getBacktraceColor();

// exception line
String message = exception.message(runtime.getCurrentContext()).toString();
Expand All @@ -325,8 +335,21 @@ protected static String printBacktraceJRuby(RubyException exception, boolean con
.append(": ")
.append(message)
.append('\n');

boolean color = console && runtime.getInstanceConfig().getBacktraceColor();

RubyStackTraceElement[] frames = exception.getBacktraceElements();
if (frames == null) frames = RubyStackTraceElement.EMPTY_ARRAY;
renderBacktraceJRuby(frames, buffer, color);


return buffer.toString();
}

private static void renderBacktraceJRuby(RubyStackTraceElement[] frames, StringBuilder buffer, boolean color) {
// find longest method name
int longestMethod = 0;
for (RubyStackTraceElement frame : frames) {
longestMethod = Math.max(longestMethod, frame.getMethodName().length());
}

// backtrace lines
boolean first = true;
Expand All @@ -341,7 +364,7 @@ protected static String printBacktraceJRuby(RubyException exception, boolean con
}
first = false;
}

buffer.append(" ");

// method name
Expand All @@ -355,16 +378,28 @@ protected static String printBacktraceJRuby(RubyException exception, boolean con
.append(frame.getFileName())
.append(':')
.append(frame.getLineNumber());

if (color) {
buffer.append(CLEAR_COLOR);
}

buffer
.append('\n');
}
}

return buffer.toString();
private static void renderBacktraceMRI(RubyStackTraceElement[] trace, StringBuilder buffer, boolean color) {
for (int i = 0; i < trace.length; i++) {
RubyStackTraceElement element = trace[i];

buffer
.append(element.getFileName())
.append(':')
.append(element.getLineNumber())
.append(":in `")
.append(element.getMethodName())
.append("'\n");
}
}

public static IRubyObject generateMRIBacktrace(Ruby runtime, RubyStackTraceElement[] trace) {
Expand Down

0 comments on commit 1735752

Please sign in to comment.