Beispiel #1
0
  private static void addBackTraceElement(
      Ruby runtime, RubyArray backtrace, Frame frame, Frame previousFrame) {
    if (frame != previousFrame
        && // happens with native exceptions, should not filter those out
        frame.getLine() == previousFrame.getLine()
        && frame.getName() != null
        && frame.getName().equals(previousFrame.getName())
        && frame.getFile().equals(previousFrame.getFile())) {
      return;
    }

    RubyString traceLine;
    if (previousFrame.getName() != null) {
      traceLine =
          RubyString.newString(
              runtime,
              frame.getFile()
                  + ':'
                  + (frame.getLine() + 1)
                  + ":in `"
                  + previousFrame.getName()
                  + '\'');
    } else if (runtime.is1_9()) {
      // TODO: This probably isn't the best hack, but it works until we can have different
      // root frame setup for 1.9 easily.
      traceLine =
          RubyString.newString(
              runtime, frame.getFile() + ':' + (frame.getLine() + 1) + ":in `<main>'");
    } else {
      traceLine = RubyString.newString(runtime, frame.getFile() + ':' + (frame.getLine() + 1));
    }

    backtrace.append(traceLine);
  }
Beispiel #2
0
 /**
  * Return a binding representing the previous call's state but with a specified self
  *
  * @param self the self object to use
  * @return the current binding, using the specified self
  */
 public Binding previousBinding(IRubyObject self) {
   Frame frame = getPreviousFrame();
   Frame current = getCurrentFrame();
   return new Binding(
       self,
       frame,
       frame.getVisibility(),
       getPreviousRubyClass(),
       getCurrentScope(),
       current.getFile(),
       current.getLine());
 }
Beispiel #3
0
  private RubyStackTraceElement[] buildTrace(RubyStackTraceElement[] newTrace) {
    for (int i = 0; i < newTrace.length; i++) {
      Frame current = frameStack[i];
      String klazzName = getClassNameFromFrame(current);
      String methodName = getMethodNameFromFrame(current);
      newTrace[newTrace.length - 1 - i] =
          new RubyStackTraceElement(
              klazzName,
              methodName,
              current.getFile(),
              current.getLine() + 1,
              current.isBindingFrame());
    }

    return newTrace;
  }
Beispiel #4
0
 public void setFileAndLine(Frame frame) {
   this.file = frame.getFile();
   this.line = frame.getLine();
 }
Beispiel #5
0
 /**
  * Return a binding representing the previous call's state
  *
  * @return the current binding
  */
 public Binding previousBinding() {
   Frame frame = getPreviousFrame();
   Frame current = getCurrentFrame();
   return new Binding(
       frame, getPreviousRubyClass(), getCurrentScope(), current.getFile(), current.getLine());
 }
Beispiel #6
0
  public static IRubyObject createRubyHybridBacktrace(
      Ruby runtime,
      RubyStackTraceElement[] backtraceFrames,
      RubyStackTraceElement[] stackTrace,
      boolean debug) {
    RubyArray traceArray = RubyArray.newArray(runtime);
    ThreadContext context = runtime.getCurrentContext();

    int rubyFrameIndex = backtraceFrames.length - 1;
    for (int i = 0; i < stackTrace.length; i++) {
      RubyStackTraceElement element = stackTrace[i];

      // look for mangling markers for compiled Ruby in method name
      int index = element.getMethodName().indexOf("$RUBY$");
      if (index >= 0) {
        String unmangledMethod = element.getMethodName().substring(index + 6);
        RubyString str =
            RubyString.newString(
                runtime,
                element.getFileName()
                    + ":"
                    + element.getLineNumber()
                    + ":in `"
                    + unmangledMethod
                    + "'");
        traceArray.append(str);

        // if it's not a rescue or ensure, there's a frame associated, so decrement
        if (!(element.getMethodName().contains("__rescue__")
            || element.getMethodName().contains("__ensure__"))) {
          rubyFrameIndex--;
        }
        continue;
      }

      // look for __file__ method name for compiled roots
      if (element.getMethodName().equals("__file__")) {
        RubyString str =
            RubyString.newString(
                runtime, element.getFileName() + ":" + element.getLineNumber() + ": `<toplevel>'");
        traceArray.append(str);
        rubyFrameIndex--;
        continue;
      }

      // look for mangling markers for bound, unframed methods in class name
      index = element.getClassName().indexOf("$RUBYINVOKER$");
      if (index >= 0) {
        // unframed invokers have no Ruby frames, so pull from class name
        // but use current frame as file and line
        String unmangledMethod = element.getClassName().substring(index + 13);
        Frame current = context.frameStack[rubyFrameIndex];
        RubyString str =
            RubyString.newString(
                runtime,
                current.getFile()
                    + ":"
                    + (current.getLine() + 1)
                    + ":in `"
                    + unmangledMethod
                    + "'");
        traceArray.append(str);
        continue;
      }

      // look for mangling markers for bound, framed methods in class name
      index = element.getClassName().indexOf("$RUBYFRAMEDINVOKER$");
      if (index >= 0) {
        // framed invokers will have Ruby frames associated with them
        addBackTraceElement(
            traceArray,
            backtraceFrames[rubyFrameIndex],
            backtraceFrames[rubyFrameIndex - 1],
            FrameType.METHOD);
        rubyFrameIndex--;
        continue;
      }

      // try to mine out a Ruby frame using our list of interpreter entry-point markers
      String classMethod = element.getClassName() + "." + element.getMethodName();
      FrameType frameType = INTERPRETED_FRAMES.get(classMethod);
      if (frameType != null) {
        // Frame matches one of our markers for "interpreted" calls
        if (rubyFrameIndex == 0) {
          addBackTraceElement(
              traceArray,
              backtraceFrames[rubyFrameIndex],
              backtraceFrames[rubyFrameIndex],
              frameType);
        } else {
          addBackTraceElement(
              traceArray,
              backtraceFrames[rubyFrameIndex],
              backtraceFrames[rubyFrameIndex - 1],
              frameType);
          rubyFrameIndex--;
        }
        continue;
      } else {
        // Frame is extraneous runtime information, skip it unless debug
        if (debug) {
          RubyString str =
              RubyString.newString(runtime, createRubyBacktraceString(element.getElement()));
          traceArray.append(str);
        }
        continue;
      }
    }

    return traceArray;
  }