Ejemplo n.º 1
0
  /**
   * Move through a list of stack frames, searching for references to code found in the current
   * sketch. Return with a RunnerException that contains the location of the error, or if nothing is
   * found, just return with a RunnerException that wraps the error message itself.
   */
  protected SketchException findException(
      String message, ObjectReference or, ThreadReference thread) {
    try {
      // use to dump the stack for debugging
      //      for (StackFrame frame : thread.frames()) {
      //        System.out.println("frame: " + frame);
      //      }

      List<StackFrame> frames = thread.frames();
      for (StackFrame frame : frames) {
        try {
          Location location = frame.location();
          String filename = null;
          filename = location.sourceName();
          int lineNumber = location.lineNumber() - 1;
          SketchException rex = build.placeException(message, filename, lineNumber);
          if (rex != null) {
            return rex;
          }
        } catch (AbsentInformationException e) {
          // Any of the thread.blah() methods can throw an AbsentInformationEx
          // if that bit of data is missing. If so, just write out the error
          // message to the console.
          // e.printStackTrace();  // not useful
          exception = new SketchException(message);
          exception.hideStackTrace();
          listener.statusError(exception);
        }
      }
    } catch (IncompatibleThreadStateException e) {
      // This shouldn't happen, but if it does, print the exception in case
      // it's something that needs to be debugged separately.
      e.printStackTrace();
    }
    // before giving up, try to extract from the throwable object itself
    // since sometimes exceptions are re-thrown from a different context
    try {
      // assume object reference is Throwable, get stack trace
      Method method =
          ((ClassType) or.referenceType())
              .concreteMethodByName("getStackTrace", "()[Ljava/lang/StackTraceElement;");
      ArrayReference result =
          (ArrayReference)
              or.invokeMethod(
                  thread, method, new ArrayList<Value>(), ObjectReference.INVOKE_SINGLE_THREADED);
      // iterate through stack frames and pull filename and line number for each
      for (Value val : result.getValues()) {
        ObjectReference ref = (ObjectReference) val;
        method =
            ((ClassType) ref.referenceType())
                .concreteMethodByName("getFileName", "()Ljava/lang/String;");
        StringReference strref =
            (StringReference)
                ref.invokeMethod(
                    thread, method, new ArrayList<Value>(), ObjectReference.INVOKE_SINGLE_THREADED);
        String filename = strref == null ? "Unknown Source" : strref.value();
        method = ((ClassType) ref.referenceType()).concreteMethodByName("getLineNumber", "()I");
        IntegerValue intval =
            (IntegerValue)
                ref.invokeMethod(
                    thread, method, new ArrayList<Value>(), ObjectReference.INVOKE_SINGLE_THREADED);
        int lineNumber = intval.intValue() - 1;
        SketchException rex = build.placeException(message, filename, lineNumber);
        if (rex != null) {
          return rex;
        }
      }
      //      for (Method m : ((ClassType) or.referenceType()).allMethods()) {
      //        System.out.println(m + " | " + m.signature() + " | " + m.genericSignature());
      //      }
      // Implemented for 2.0b9, writes a stack trace when there's an internal error inside core.
      method = ((ClassType) or.referenceType()).concreteMethodByName("printStackTrace", "()V");
      //      System.err.println("got method " + method);
      or.invokeMethod(
          thread, method, new ArrayList<Value>(), ObjectReference.INVOKE_SINGLE_THREADED);

    } catch (Exception e) {
      e.printStackTrace();
    }
    // Give up, nothing found inside the pile of stack frames
    SketchException rex = new SketchException(message);
    // exception is being created /here/, so stack trace is not useful
    rex.hideStackTrace();
    return rex;
  }
Ejemplo n.º 2
0
  public void breakpointReached(BreakpointEvent event) {
    String origMethodName = event.location().method().name();
    String methodName = origMethodName.substring(2);
    ThreadReference tr = event.thread();

    if (vm().canForceEarlyReturn()) {

      try {

        if ("bytef".equals(methodName)) {
          Field theValueField = targetClass.fieldByName("ebyteValue");
          ByteValue theValue = (ByteValue) targetClass.getValue(theValueField);
          tr.forceEarlyReturn(theValue);
          /*
           * See what happens if we access the stack after the force
           * and before the resume.  Disabling this since spec says
           * the stack is undefined.  This type of code can be used to
           * pursue just what that means.
           *
           * StackFrame sf = tr.frame(0);
           * List<Value> ll = sf.getArgumentValues();
           * for (Value vv: ll) {
           *     System.out.println("vv = " + vv);
           * }
           */
        } else if ("charf".equals(methodName)) {
          Field theValueField = targetClass.fieldByName("echarValue");
          CharValue theValue = (CharValue) targetClass.getValue(theValueField);
          tr.forceEarlyReturn(theValue);
        } else if ("doublef".equals(methodName)) {
          Field theValueField = targetClass.fieldByName("edoubleValue");
          DoubleValue theValue = (DoubleValue) targetClass.getValue(theValueField);
          tr.forceEarlyReturn(theValue);
        } else if ("floatf".equals(methodName)) {
          Field theValueField = targetClass.fieldByName("efloatValue");
          FloatValue theValue = (FloatValue) targetClass.getValue(theValueField);
          tr.forceEarlyReturn(theValue);
        } else if ("intf".equals(methodName)) {
          Field theValueField = targetClass.fieldByName("eintValue");
          IntegerValue theValue = (IntegerValue) targetClass.getValue(theValueField);
          tr.forceEarlyReturn(theValue);
        } else if ("longf".equals(methodName)) {
          Field theValueField = targetClass.fieldByName("elongValue");
          LongValue theValue = (LongValue) targetClass.getValue(theValueField);
          tr.forceEarlyReturn(theValue);
        } else if ("shortf".equals(methodName)) {
          Field theValueField = targetClass.fieldByName("eshortValue");
          ShortValue theValue = (ShortValue) targetClass.getValue(theValueField);
          tr.forceEarlyReturn(theValue);
        } else if ("booleanf".equals(methodName)) {
          Field theValueField = targetClass.fieldByName("ebooleanValue");
          BooleanValue theValue = (BooleanValue) targetClass.getValue(theValueField);
          tr.forceEarlyReturn(theValue);
        } else if ("stringf".equals(methodName)) {
          Field theValueField = targetClass.fieldByName("estringValue");
          StringReference theValue = (StringReference) targetClass.getValue(theValueField);
          tr.forceEarlyReturn(theValue);
        } else if ("classf".equals(methodName)) {
          Field theValueField = targetClass.fieldByName("eclassValue");
          ClassObjectReference theValue =
              (ClassObjectReference) targetClass.getValue(theValueField);
          tr.forceEarlyReturn(theValue);
        } else if ("classLoaderf".equals(methodName)) {
          Field theValueField = targetClass.fieldByName("eclassLoaderValue");
          ClassLoaderReference theValue =
              (ClassLoaderReference) targetClass.getValue(theValueField);
          tr.forceEarlyReturn(theValue);
        } else if ("threadf".equals(methodName)) {
          Field theValueField = targetClass.fieldByName("ethreadValue");
          ThreadReference theValue = (ThreadReference) targetClass.getValue(theValueField);
          tr.forceEarlyReturn(theValue);
        } else if ("threadGroupf".equals(methodName)) {
          Field theValueField = targetClass.fieldByName("ethreadGroupValue");
          ThreadGroupReference theValue =
              (ThreadGroupReference) targetClass.getValue(theValueField);
          tr.forceEarlyReturn(theValue);
        } else if ("intArrayf".equals(methodName)) {
          Field theValueField = targetClass.fieldByName("eintArrayValue");
          ArrayReference theValue = (ArrayReference) targetClass.getValue(theValueField);
          tr.forceEarlyReturn(theValue);
        } else if ("nullObjectf".equals(methodName)) {
          tr.forceEarlyReturn(null);
        } else if ("objectf".equals(methodName)) {
          Field theValueField = targetClass.fieldByName("eobjectValue");
          ObjectReference theValue = (ObjectReference) targetClass.getValue(theValueField);
          tr.forceEarlyReturn(theValue);
        } else if ("voidf".equals(methodName)) {
          VoidValue theValue = vm().mirrorOfVoid();
          tr.forceEarlyReturn(theValue);
        } else {
          failure("failure: Unknown methodName: " + origMethodName);
        }

      } catch (Exception ex) {
        failure("failure: " + ex.toString());
        ex.printStackTrace();
      }
    } else {
      System.out.println("Cannot force early return for method: " + origMethodName);
    }
  }