Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: b71379ef6d64^
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 257e7301f603
Choose a head ref
  • 8 commits
  • 4 files changed
  • 1 contributor

Commits on Aug 7, 2015

  1. cleanup JRubyFile

    kares committed Aug 7, 2015
    Copy the full SHA
    b71379e View commit details
  2. Copy the full SHA
    3954eaf View commit details
  3. Copy the full SHA
    c9183ef View commit details
  4. save an interim builder+string with mangleStringForCleanJavaIdentifier

    + guess string builder length for possibly less internal array resizing
    kares committed Aug 7, 2015
    Copy the full SHA
    5679014 View commit details

Commits on Aug 8, 2015

  1. cleanup test_backtraces

    kares committed Aug 8, 2015
    Copy the full SHA
    c1e8e92 View commit details
  2. Copy the full SHA
    32a1194 View commit details
  3. Copy the full SHA
    f94acc6 View commit details
  4. improve backtrace rewriting when native exception is re-thrown (fixes #…

    …3177)
    
    ... some parts e.g. Java based core-methods had their filename part incorrect when re-thrown (adding package prefix path twice)
    kares committed Aug 8, 2015
    Copy the full SHA
    257e730 View commit details
58 changes: 22 additions & 36 deletions core/src/main/java/org/jruby/runtime/backtrace/BacktraceData.java
Original file line number Diff line number Diff line change
@@ -66,15 +66,12 @@ private RubyStackTraceElement[] transformBacktrace(Map<String, Map<String, Strin
// Don't process .java files
if (!filename.endsWith(".java")) {

boolean compiled = false;
int index;
boolean compiled = false; int index;

// Check for compiled name markers
// FIXME: Formalize jitted method structure so this isn't quite as hacky
if (className.startsWith(JITCompiler.RUBY_JIT_PREFIX)) {

// JIT-compiled code
compiled = true;
compiled = true; // JIT-compiled code

// pull out and demangle the method name
String tmpClassName = className;
@@ -87,9 +84,7 @@ private RubyStackTraceElement[] transformBacktrace(Map<String, Map<String, Strin
methodName = tmpClassName.substring(hash + JITCompiler.CLASS_METHOD_DELIMITER.length(), end);

} else if ((index = methodName.indexOf("$RUBY$")) >= 0) {

// AOT-compiled code
compiled = true;
compiled = true; // AOT-compiled code

// pull out and demangle the method name
index += "$RUBY$".length();
@@ -128,38 +123,30 @@ private RubyStackTraceElement[] transformBacktrace(Map<String, Map<String, Strin
}

// Java-based Ruby core methods
String rubyName = null;
if (
fullTrace || // full traces show all elements
(rubyName = getBoundMethodName(boundMethods, className, methodName)) != null // if a bound Java impl, always show
) {

if (rubyName == null) rubyName = methodName;
String rubyName = methodName; // when fullTrace == true
if ( fullTrace || // full traces show all elements
( rubyName = getBoundMethodName(boundMethods, className, methodName) ) != null ) { // if a bound Java impl, always show

// add package to filename
filename = packagedFilenameFromElement(filename, className);

// mask .java frames out for e.g. Kernel#caller
if (maskNative) {
// for Kernel#caller, don't show .java frames in the trace
dupFrame = true;
dupFrameName = rubyName;
continue;
dupFrame = true; dupFrameName = rubyName; continue;
}

// construct Ruby trace element
trace.add(new RubyStackTraceElement(className, rubyName, filename, line, false));

// if not full trace, we're done; don't check interpreted marker
if (!fullTrace) {
continue;
}
if ( ! fullTrace ) continue;
}

// Interpreted frames
if (rubyFrameIndex >= 0 &&
FrameType.INTERPRETED_CLASSES.contains(className) &&
FrameType.INTERPRETED_FRAMES.containsKey(methodName)) {
if ( rubyFrameIndex >= 0 &&
FrameType.INTERPRETED_CLASSES.contains(className) &&
FrameType.INTERPRETED_FRAMES.containsKey(methodName) ) {

// pop interpreter frame
BacktraceElement rubyFrame = rubyTrace[rubyFrameIndex--];
@@ -179,13 +166,8 @@ private RubyStackTraceElement[] transformBacktrace(Map<String, Map<String, Strin

// if all else fails and this is a non-JRuby element we want to include, add it
if (includeNonFiltered && !isFilteredClass(className)) {
trace.add(new RubyStackTraceElement(
className,
methodName,
packagedFilenameFromElement(filename, className),
line,
false
));
filename = packagedFilenameFromElement(filename, className);
trace.add(new RubyStackTraceElement(className, methodName, filename, line, false));
}
}

@@ -201,15 +183,19 @@ public static String getBoundMethodName(Map<String,Map<String,String>> boundMeth
return javaToRuby.get(methodName);
}

private static String packagedFilenameFromElement(String filename, String className) {
private static String packagedFilenameFromElement(final String filename, final String className) {
// stick package on the beginning
if (filename == null) {
return className.replace('.', '/');
}
if (filename == null) return className.replace('.', '/');

int lastDot = className.lastIndexOf('.');
if (lastDot == -1) return filename;
return className.substring(0, lastDot + 1).replace('.', '/') + filename;

final String pkgPath = className.substring(0, lastDot + 1).replace('.', '/');
// in case a native exception is re-thrown we might end-up rewriting twice e.g. :
// 1st time className = org.jruby.RubyArray filename = RubyArray.java
// 2nd time className = org.jruby.RubyArray filename = org/jruby/RubyArray.java
if (filename.indexOf('/') > -1 && filename.startsWith(pkgPath)) return filename;
return pkgPath + filename;
}

// ^(org\\.jruby)|(sun\\.reflect)
79 changes: 36 additions & 43 deletions core/src/main/java/org/jruby/util/JRubyFile.java
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@
* rights and limitations under the License.
*
* Copyright (C) 2006 Ola Bini <ola@ologix.com>
*
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
@@ -35,20 +35,15 @@
import java.io.FilenameFilter;
import java.io.IOException;

import jnr.posix.JavaSecuredFile;
import jnr.posix.POSIX;
import org.jruby.Ruby;
import org.jruby.RubyFile;
import org.jruby.runtime.ThreadContext;

import jnr.posix.JavaSecuredFile;
import org.jruby.Ruby;
import org.jruby.platform.Platform;
import java.util.jar.JarFile;
import java.util.jar.JarEntry;
import java.util.zip.ZipEntry;
import java.io.IOException;
import org.jruby.runtime.ThreadContext;

/**
* <p>This file acts as an alternative to NormalizedFile, due to the problems with current working
* <p>This file acts as an alternative to NormalizedFile, due to the problems with current working
* directory.</p>
*
*/
@@ -84,7 +79,7 @@ public static FileResource createResource(POSIX posix, Ruby runtime, String cwd,
FileResource jarResource = JarResource.create(pathname);
if (jarResource != null) return jarResource;

if (pathname.contains(":")) { // scheme-oriented resources
if (pathname.indexOf(':') > 0) { // scheme-oriented resources
if (pathname.startsWith("classpath:")) return ClasspathResource.create(pathname);

// replace is needed for maven/jruby-complete/src/it/app_using_classpath_uri to work
@@ -93,13 +88,13 @@ public static FileResource createResource(POSIX posix, Ruby runtime, String cwd,
if (pathname.startsWith("file:")) {
pathname = pathname.substring(5);

if ("".equals(pathname)) return EmptyFileResource.create(pathname);
if (pathname.length() == 0) return EmptyFileResource.create(pathname);
}
}

File internal = new JavaSecuredFile(pathname);
if (cwd != null && !internal.isAbsolute() && (cwd.startsWith("uri:") || cwd.startsWith("file:"))) {
return createResource(posix, runtime, null, cwd + "/" + pathname);
return createResource(posix, runtime, null, cwd + '/' + pathname);
}

// If any other special resource types fail, count it as a filesystem backed resource.
@@ -110,13 +105,12 @@ public static FileResource createResource(POSIX posix, Ruby runtime, String cwd,
public static String normalizeSeps(String path) {
if (Platform.IS_WINDOWS) {
return path.replace(File.separatorChar, '/');
} else {
return path;
}
return path;
}

private static JRubyFile createNoUnicodeConversion(String cwd, String pathname) {
if (pathname == null || pathname.equals("") || Ruby.isSecurityRestricted()) {
if (pathname == null || pathname.length() == 0 || Ruby.isSecurityRestricted()) {
return JRubyNonExistentFile.NOT_EXIST;
}
if(pathname.startsWith("file:")) {
@@ -127,7 +121,7 @@ private static JRubyFile createNoUnicodeConversion(String cwd, String pathname)
return new JRubyFile(internal);
}
if(cwd != null && cwd.startsWith("uri:") && !pathname.startsWith("uri:") && !pathname.contains("!/")) {
return new JRubyFile(cwd + "/" + pathname);
return new JRubyFile(cwd + '/' + pathname);
}
internal = new JavaSecuredFile(cwd, pathname);
if(!internal.isAbsolute()) {
@@ -150,29 +144,31 @@ protected JRubyFile(String filename) {

@Override
public String getAbsolutePath() {
if(super.getPath().startsWith("uri:")) {
final String path = super.getPath();
if (path.startsWith("uri:")) {
// TODO better do not collapse // to / for uri: files
return super.getPath().replaceFirst(":/([^/])", "://$1" );
return path.replaceFirst(":/([^/])", "://$1" );
}
return normalizeSeps(new File(super.getPath()).getAbsolutePath());
return normalizeSeps(new File(path).getAbsolutePath());
}

@Override
public String getCanonicalPath() throws IOException {
try {
return normalizeSeps(super.getCanonicalPath());
} catch (IOException e) {
// usually IOExceptions don't tell us anything about the path,
// so add an extra wrapper to give more debugging help.
throw (IOException) new IOException("Unable to canonicalize path: " + getAbsolutePath()).initCause(e);
}
try {
return normalizeSeps(super.getCanonicalPath());
}
catch (IOException e) {
// usually IOExceptions don't tell us anything about the path,
// so add an extra wrapper to give more debugging help.
throw new IOException("Unable to canonicalize path: " + getAbsolutePath(), e);
}
}

@Override
public String getPath() {
return normalizeSeps(super.getPath());
}

@Override
public String toString() {
return normalizeSeps(super.toString());
@@ -190,21 +186,18 @@ public File getCanonicalFile() throws IOException {

@Override
public String getParent() {
String par = super.getParent();
if (par != null) {
par = normalizeSeps(par);
String parent = super.getParent();
if (parent != null) {
parent = normalizeSeps(parent);
}
return par;
return parent;
}

@Override
public File getParentFile() {
String par = getParent();
if (par == null) {
return this;
} else {
return new JRubyFile(par);
}
String parent = getParent();
if (parent == null) return this;
return new JRubyFile(parent);
}

public static File[] listRoots() {
@@ -244,7 +237,7 @@ public File[] listFiles() {
if (files == null) {
return null;
}

JRubyFile[] smartFiles = new JRubyFile[files.length];
for (int i = 0, j = files.length; i < j; i++) {
smartFiles[i] = createNoUnicodeConversion(super.getAbsolutePath(), files[i].getPath());
@@ -258,7 +251,7 @@ public File[] listFiles(final FileFilter filter) {
if (files == null) {
return null;
}

JRubyFile[] smartFiles = new JRubyFile[files.length];
for (int i = 0,j = files.length; i < j; i++) {
smartFiles[i] = createNoUnicodeConversion(super.getAbsolutePath(), files[i].getPath());
@@ -272,7 +265,7 @@ public File[] listFiles(final FilenameFilter filter) {
if (files == null) {
return null;
}

JRubyFile[] smartFiles = new JRubyFile[files.length];
for (int i = 0,j = files.length; i < j; i++) {
smartFiles[i] = createNoUnicodeConversion(super.getAbsolutePath(), files[i].getPath());
Loading