示例#1
0
  @Override
  public List<IWatchable> getVisibleWatchables() {
    try {
      StackFrame stackFrame = getStackFrame();
      List<IWatchable> result = new ArrayList<IWatchable>();

      if (stackFrame != null) {
        for (LocalVariable variable : stackFrame.visibleVariables()) {
          result.add(new JavaLocalVariable(variable, this, myClassFqName, myThreadReference));
        }

        ObjectReference thisObject = stackFrame.thisObject();
        if (thisObject != null) {
          result.add(new JavaThisObject(thisObject, this, myClassFqName, myThreadReference));
        } else {
          result.add(
              new JavaStaticContext(
                  getStackFrame().location().declaringType(), myClassFqName, myThreadReference));
        }
      }

      return result;
    } catch (InvalidStackFrameException ex) {
      LOG.warning(
          "InvalidStackFrameException",
          ex); // TODO something should be done here. See, for instance, how idea deals with those
               // exceptions
      return Collections.emptyList();
    } catch (AbsentInformationException ex) {
      // doing nothing, variables are just not available for us
      return Collections.emptyList();
    }
  }
示例#2
0
 private void dumpStack(ThreadReference thread, boolean showPC) {
   // ### Check for these.
   // env.failure("Thread no longer exists.");
   // env.failure("Target VM must be in interrupted state.");
   // env.failure("Current thread isn't suspended.");
   // ### Should handle extremely long stack traces sensibly for user.
   List<StackFrame> stack = null;
   try {
     stack = thread.frames();
   } catch (IncompatibleThreadStateException e) {
     env.failure("Thread is not suspended.");
   }
   // ### Fix this!
   // ### Previously mishandled cases where thread was not current.
   // ### Now, prints all of the stack regardless of current frame.
   int frameIndex = 0;
   // int frameIndex = context.getCurrentFrameIndex();
   if (stack == null) {
     env.failure("Thread is not running (no stack).");
   } else {
     OutputSink out = env.getOutputSink();
     int nFrames = stack.size();
     for (int i = frameIndex; i < nFrames; i++) {
       StackFrame frame = stack.get(i);
       Location loc = frame.location();
       Method meth = loc.method();
       out.print("  [" + (i + 1) + "] ");
       out.print(meth.declaringType().name());
       out.print('.');
       out.print(meth.name());
       out.print(" (");
       if (meth.isNative()) {
         out.print("native method");
       } else if (loc.lineNumber() != -1) {
         try {
           out.print(loc.sourceName());
         } catch (AbsentInformationException e) {
           out.print("<unknown>");
         }
         out.print(':');
         out.print(loc.lineNumber());
       }
       out.print(')');
       if (showPC) {
         long pc = loc.codeIndex();
         if (pc != -1) {
           out.print(", pc = " + pc);
         }
       }
       out.println();
     }
     out.show();
   }
 }
  protected void runTests() throws Exception {
    /*
     * Get to the top of main()
     * to determine targetClass and mainThread
     */
    BreakpointEvent bpe = startToMain("GetLocalVariables2Targ");
    targetClass = bpe.location().declaringType();
    mainThread = bpe.thread();
    EventRequestManager erm = vm().eventRequestManager();

    bpe = resumeTo("GetLocalVariables2Targ", "bar", "(I)Z");

    /*
     * Inspect the stack frame for main(), not bar()...
     */
    StackFrame frame = bpe.thread().frame(1);
    List localVars = frame.visibleVariables();
    System.out.println("    Visible variables at this point are: ");
    for (Iterator it = localVars.iterator(); it.hasNext(); ) {
      LocalVariable lv = (LocalVariable) it.next();
      System.out.print(lv.name());
      System.out.print(" typeName: ");
      System.out.print(lv.typeName());
      System.out.print(" signature: ");
      System.out.print(lv.type().signature());
      System.out.print(" primitive type: ");
      System.out.println(lv.type().name());

      if ("command".equals(lv.name())) {
        failure("Failure: LocalVariable \"command\" should not be visible at this point.");
        if (lv.isVisible(frame)) {
          System.out.println("Failure: \"command.isvisible(frame)\" returned true.");
        }
      }
    }

    /*
     * resume the target listening for events
     */
    listenUntilVMDisconnect();

    /*
     * deal with results of test
     * if anything has called failure("foo") testFailed will be true
     */
    if (!testFailed) {
      println("GetLocalVariables2Test: passed");
    } else {
      throw new Exception("GetLocalVariables2Test: failed");
    }
  }
示例#4
0
  private void commandLocals() throws NoSessionException {
    ThreadReference current = context.getCurrentThread();
    if (current == null) {
      env.failure("No default thread specified: " + "use the \"thread\" command first.");
      return;
    }
    StackFrame frame;
    try {
      frame = context.getCurrentFrame(current);
      if (frame == null) {
        env.failure("Thread has not yet created any stack frames.");
        return;
      }
    } catch (VMNotInterruptedException e) {
      env.failure("Target VM must be in interrupted state.");
      return;
    }

    List<LocalVariable> vars;
    try {
      vars = frame.visibleVariables();
      if (vars == null || vars.size() == 0) {
        env.failure("No local variables");
        return;
      }
    } catch (AbsentInformationException e) {
      env.failure(
          "Local variable information not available."
              + " Compile with -g to generate variable information");
      return;
    }

    OutputSink out = env.getOutputSink();
    out.println("Method arguments:");
    for (LocalVariable var : vars) {
      if (var.isArgument()) {
        printVar(out, var, frame);
      }
    }
    out.println("Local variables:");
    for (LocalVariable var : vars) {
      if (!var.isArgument()) {
        printVar(out, var, frame);
      }
    }
    out.show();
    return;
  }
示例#5
0
 @Override
 public Map<IWatchable, IValue> getWatchableValues() {
   try {
     StackFrame stackFrame = getStackFrame();
     Map<IWatchable, IValue> result = new HashMap<IWatchable, IValue>();
     if (stackFrame != null) {
       Map<LocalVariable, Value> map = stackFrame.getValues(stackFrame.visibleVariables());
       for (LocalVariable variable : map.keySet()) {
         result.put(
             new JavaLocalVariable(variable, this, myClassFqName, stackFrame.thread()),
             JavaValue.fromJDIValue(map.get(variable), myClassFqName, stackFrame.thread()));
       }
       ObjectReference thisObject = stackFrame.thisObject();
       if (thisObject != null) {
         JavaThisObject object =
             new JavaThisObject(thisObject, this, myClassFqName, stackFrame.thread());
         result.put(object, object.getValue());
       }
     }
     return result;
   } catch (AbsentInformationException ex) {
     // doing nothing
     return Collections.emptyMap();
   }
 }
示例#6
0
 private void printVar(OutputSink out, LocalVariable var, StackFrame frame) {
   out.print("  " + var.name());
   if (var.isVisible(frame)) {
     Value val = frame.getValue(var);
     out.println(" = " + val.toString());
   } else {
     out.println(" is not in scope");
   }
 }
 /** Called when a script exception has been thrown. */
 private void handleExceptionThrown(Context cx, Throwable ex, StackFrame frame) {
   if (breakOnExceptions) {
     ContextData cd = frame.contextData();
     if (cd.lastProcessedException != ex) {
       interrupted(cx, frame, ex);
       cd.lastProcessedException = ex;
     }
   }
 }
示例#8
0
 private void commandList(StringTokenizer t) throws NoSessionException {
   ThreadReference current = context.getCurrentThread();
   if (current == null) {
     env.error("No thread specified.");
     return;
   }
   Location loc;
   try {
     StackFrame frame = context.getCurrentFrame(current);
     if (frame == null) {
       env.failure("Thread has not yet begun execution.");
       return;
     }
     loc = frame.location();
   } catch (VMNotInterruptedException e) {
     env.failure("Target VM must be in interrupted state.");
     return;
   }
   SourceModel source = sourceManager.sourceForLocation(loc);
   if (source == null) {
     if (loc.method().isNative()) {
       env.failure("Current method is native.");
       return;
     }
     env.failure("No source available for " + Utils.locationString(loc) + ".");
     return;
   }
   ReferenceType refType = loc.declaringType();
   int lineno = loc.lineNumber();
   if (t.hasMoreTokens()) {
     String id = t.nextToken();
     // See if token is a line number.
     try {
       lineno = Integer.valueOf(id).intValue();
     } catch (NumberFormatException nfe) {
       // It isn't -- see if it's a method name.
       List<Method> meths = refType.methodsByName(id);
       if (meths == null || meths.size() == 0) {
         env.failure(
             id + " is not a valid line number or " + "method name for class " + refType.name());
         return;
       } else if (meths.size() > 1) {
         env.failure(id + " is an ambiguous method name in" + refType.name());
         return;
       }
       loc = meths.get(0).location();
       lineno = loc.lineNumber();
     }
   }
   int startLine = (lineno > 4) ? lineno - 4 : 1;
   int endLine = startLine + 9;
   String sourceLine = source.sourceLine(lineno);
   if (sourceLine == null) {
     env.failure("" + lineno + " is an invalid line number for " + refType.name());
   } else {
     OutputSink out = env.getOutputSink();
     for (int i = startLine; i <= endLine; i++) {
       sourceLine = source.sourceLine(i);
       if (sourceLine == null) {
         break;
       }
       out.print(i);
       out.print("\t");
       if (i == lineno) {
         out.print("=> ");
       } else {
         out.print("   ");
       }
       out.println(sourceLine);
     }
     out.show();
   }
 }
示例#9
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;
  }
示例#10
0
 @Override
 public JavaThread getThread() {
   StackFrame stackFrame = getStackFrame();
   if (stackFrame == null) return null;
   return new JavaThread(stackFrame.thread());
 }
示例#11
0
 @Override
 public JavaLocation getLocation() {
   StackFrame stackFrame = getStackFrame();
   if (stackFrame == null) return null;
   return new JavaLocation(stackFrame.location());
 }
  /** Interrupts script execution. */
  private void interrupted(Context cx, final StackFrame frame, Throwable scriptException) {
    ContextData contextData = frame.contextData();
    boolean eventThreadFlag = callback.isGuiEventThread();
    contextData.eventThreadFlag = eventThreadFlag;

    boolean recursiveEventThreadCall = false;

    interruptedCheck:
    synchronized (eventThreadMonitor) {
      if (eventThreadFlag) {
        if (interruptedContextData != null) {
          recursiveEventThreadCall = true;
          break interruptedCheck;
        }
      } else {
        while (interruptedContextData != null) {
          try {
            eventThreadMonitor.wait();
          } catch (InterruptedException exc) {
            return;
          }
        }
      }
      interruptedContextData = contextData;
    }

    if (recursiveEventThreadCall) {
      // XXX: For now the following is commented out as on Linux
      // too deep recursion of dispatchNextGuiEvent causes GUI lockout.
      // Note: it can make GUI unresponsive if long-running script
      // will be called on GUI thread while processing another interrupt
      if (false) {
        // Run event dispatch until gui sets a flag to exit the initial
        // call to interrupted.
        while (this.returnValue == -1) {
          try {
            callback.dispatchNextGuiEvent();
          } catch (InterruptedException exc) {
          }
        }
      }
      return;
    }

    if (interruptedContextData == null) Kit.codeBug();

    try {
      do {
        int frameCount = contextData.frameCount();
        this.frameIndex = frameCount - 1;

        final String threadTitle = Thread.currentThread().toString();
        final String alertMessage;
        if (scriptException == null) {
          alertMessage = null;
        } else {
          alertMessage = scriptException.toString();
        }

        int returnValue = -1;
        if (!eventThreadFlag) {
          synchronized (monitor) {
            if (insideInterruptLoop) Kit.codeBug();
            this.insideInterruptLoop = true;
            this.evalRequest = null;
            this.returnValue = -1;
            callback.enterInterrupt(frame, threadTitle, alertMessage);
            try {
              for (; ; ) {
                try {
                  monitor.wait();
                } catch (InterruptedException exc) {
                  Thread.currentThread().interrupt();
                  break;
                }
                if (evalRequest != null) {
                  this.evalResult = null;
                  try {
                    evalResult = do_eval(cx, evalFrame, evalRequest);
                  } finally {
                    evalRequest = null;
                    evalFrame = null;
                    monitor.notify();
                  }
                  continue;
                }
                if (this.returnValue != -1) {
                  returnValue = this.returnValue;
                  break;
                }
              }
            } finally {
              insideInterruptLoop = false;
            }
          }
        } else {
          this.returnValue = -1;
          callback.enterInterrupt(frame, threadTitle, alertMessage);
          while (this.returnValue == -1) {
            try {
              callback.dispatchNextGuiEvent();
            } catch (InterruptedException exc) {
            }
          }
          returnValue = this.returnValue;
        }
        switch (returnValue) {
          case STEP_OVER:
            contextData.breakNextLine = true;
            contextData.stopAtFrameDepth = contextData.frameCount();
            break;
          case STEP_INTO:
            contextData.breakNextLine = true;
            contextData.stopAtFrameDepth = -1;
            break;
          case STEP_OUT:
            if (contextData.frameCount() > 1) {
              contextData.breakNextLine = true;
              contextData.stopAtFrameDepth = contextData.frameCount() - 1;
            }
            break;
        }
      } while (false);
    } finally {
      synchronized (eventThreadMonitor) {
        interruptedContextData = null;
        eventThreadMonitor.notifyAll();
      }
    }
  }