Пример #1
0
 private void commandWhere(StringTokenizer t, boolean showPC) throws NoSessionException {
   ThreadReference current = context.getCurrentThread();
   if (!t.hasMoreTokens()) {
     if (current == null) {
       env.error("No thread specified.");
       return;
     }
     dumpStack(current, showPC);
   } else {
     String token = t.nextToken();
     if (token.toLowerCase().equals("all")) {
       ThreadIterator it = allThreads();
       while (it.hasNext()) {
         ThreadReference thread = it.next();
         out.println(thread.name() + ": ");
         dumpStack(thread, showPC);
       }
     } else {
       ThreadReference thread = findThread(t.nextToken());
       // ### Do we want to set current thread here?
       // ### Should notify user of change.
       if (thread != null) {
         context.setCurrentThread(thread);
       }
       dumpStack(thread, showPC);
     }
   }
 }
Пример #2
0
 private ThreadReference findThread(String idToken) throws NoSessionException {
   String id;
   ThreadReference thread = null;
   if (idToken.startsWith("t@")) {
     id = idToken.substring(2);
   } else {
     id = idToken;
   }
   try {
     ThreadReference[] threads = threads();
     long threadID = Long.parseLong(id, 16);
     for (ThreadReference thread2 : threads) {
       if (thread2.uniqueID() == threadID) {
         thread = thread2;
         break;
       }
     }
     if (thread == null) {
       // env.failure("No thread for id \"" + idToken + "\"");
       env.failure("\"" + idToken + "\" is not a valid thread id.");
     }
   } catch (NumberFormatException e) {
     env.error("Thread id \"" + idToken + "\" is ill-formed.");
     thread = null;
   }
   return thread;
 }
Пример #3
0
 private void commandKill(StringTokenizer t) throws NoSessionException {
   // ### Should change the way in which thread ids and threadgroup names
   // ### are distinguished.
   if (!t.hasMoreTokens()) {
     env.error("Usage: kill <threadgroup name> or <thread id>");
     return;
   }
   while (t.hasMoreTokens()) {
     String idToken = t.nextToken();
     ThreadReference thread = findThread(idToken);
     if (thread != null) {
       runtime.stopThread(thread);
       env.notice("Thread " + thread.name() + " killed.");
       return;
     } else {
       /* Check for threadgroup name, NOT skipping "system". */
       // ### Should skip "system"?  Classic 'jdb' does this.
       // ### Should deal with possible non-uniqueness of threadgroup names.
       ThreadGroupIterator itg = allThreadGroups();
       while (itg.hasNext()) {
         ThreadGroupReference tg = itg.nextThreadGroup();
         if (tg.name().equals(idToken)) {
           ThreadIterator it = new ThreadIterator(tg);
           while (it.hasNext()) {
             runtime.stopThread(it.nextThread());
           }
           env.notice("Threadgroup " + tg.name() + "killed.");
           return;
         }
       }
       env.failure("\"" + idToken + "\" is not a valid threadgroup or id.");
     }
   }
 }
Пример #4
0
 @Override
 protected boolean shouldResume(Event event) {
   // Is this the thread we are interested in?
   ThreadReference thread = null;
   if (event instanceof ThreadStartEvent && onStart) {
     thread = ((ThreadStartEvent) event).thread();
   } else if (event instanceof ThreadDeathEvent && onDeath) {
     thread = ((ThreadDeathEvent) event).thread();
   } else {
     return true;
   }
   String name = null;
   try {
     name = thread.name();
   } catch (VMDisconnectedException vmde) {
     // Happens when event does not suspend.
     return true;
   }
   String filter = getThreadFilter();
   if (filter != null && filter.length() > 0) {
     return !filter.equals(name);
   }
   // Delegate to the superclass to check any conditions.
   return super.shouldResume(event);
 }
Пример #5
0
  private int printThreadGroup(OutputSink out, ThreadGroupReference tg, int iThread) {
    out.println("Group " + tg.name() + ":");
    List<ThreadReference> tlist = tg.threads();
    int maxId = 0;
    int maxName = 0;
    for (int i = 0; i < tlist.size(); i++) {
      ThreadReference thr = tlist.get(i);
      int len = Utils.description(thr).length();
      if (len > maxId) {
        maxId = len;
      }
      String name = thr.name();
      int iDot = name.lastIndexOf('.');
      if (iDot >= 0 && name.length() > iDot) {
        name = name.substring(iDot + 1);
      }
      if (name.length() > maxName) {
        maxName = name.length();
      }
    }
    String maxNumString = String.valueOf(iThread + tlist.size());
    int maxNumDigits = maxNumString.length();
    for (int i = 0; i < tlist.size(); i++) {
      ThreadReference thr = tlist.get(i);
      char buf[] = new char[80];
      for (int j = 0; j < 79; j++) {
        buf[j] = ' ';
      }
      buf[79] = '\0';
      StringBuffer sbOut = new StringBuffer();
      sbOut.append(buf);

      // Right-justify the thread number at start of output string
      String numString = String.valueOf(iThread + i + 1);
      sbOut.insert(maxNumDigits - numString.length(), numString);
      sbOut.insert(maxNumDigits, ".");

      int iBuf = maxNumDigits + 2;
      sbOut.insert(iBuf, Utils.description(thr));
      iBuf += maxId + 1;
      String name = thr.name();
      int iDot = name.lastIndexOf('.');
      if (iDot >= 0 && name.length() > iDot) {
        name = name.substring(iDot + 1);
      }
      sbOut.insert(iBuf, name);
      iBuf += maxName + 1;
      sbOut.insert(iBuf, Utils.getStatus(thr));
      sbOut.setLength(79);
      out.println(sbOut.toString());
    }
    for (ThreadGroupReference tg0 : tg.threadGroups()) {
      if (!tg.equals(tg0)) { // TODO ref mgt
        iThread += printThreadGroup(out, tg0, iThread + tlist.size());
      }
    }
    return tlist.size();
  }
Пример #6
0
 /**
  * Set the current stackframe to a specific frame.
  *
  * @param nFrame the number of the desired stackframe. Frame zero is the closest to the current
  *     program counter
  * @throws IllegalAccessError when the thread isn't suspended or waiting at a breakpoint
  * @throws ArrayIndexOutOfBoundsException when the requested frame is beyond the stack boundary
  */
 public void setCurrentFrameIndex(int nFrame) throws IncompatibleThreadStateException {
   assureSuspended();
   if ((nFrame < 0) || (nFrame >= thread.frameCount())) {
     throw new ArrayIndexOutOfBoundsException();
   }
   currentFrameIndex = nFrame;
 }
Пример #7
0
 @Nullable
 public StackFrame getStackFrame() {
   try {
     return myThreadReference.frame(myIndex);
   } catch (Throwable t) {
     LOG.error(t);
     return null;
   }
 }
Пример #8
0
 public List<LocalVariable> getLocals(ThreadReference tr, int idx)
     throws IllegalArgumentException, IncompatibleThreadStateException,
         AbsentInformationException {
   StackFrame frame = tr.frames().get(idx);
   if (frame != null) {
     return frame.visibleVariables();
   }
   return null;
 }
Пример #9
0
 public void resume() {
   switch (suspendPolicy()) {
     case EventRequest.SUSPEND_ALL:
       vm.resume();
       break;
     case EventRequest.SUSPEND_EVENT_THREAD:
       ThreadReference thread = eventThread();
       if (thread == null) {
         throw new InternalException("Inconsistent suspend policy");
       }
       thread.resume();
       break;
     case EventRequest.SUSPEND_NONE:
       // Do nothing
       break;
     default:
       throw new InternalException("Invalid suspend policy");
   }
 }
Пример #10
0
 public Value getLocalVariableValue(ThreadReference tr, int frameIdx, String localName)
     throws AbsentInformationException, IncompatibleThreadStateException {
   StackFrame fr = tr.frame(frameIdx);
   Value ret = null;
   LocalVariable var = fr.visibleVariableByName(localName);
   if (var != null) {
     ret = fr.getValue(var);
   }
   return ret;
 }
Пример #11
0
 /** if this line can not be current => stepOver & return true. return false on the other hand. */
 boolean resolveCanBeCurrent(ThreadReference tr) {
   try {
     Location l = tr.frame(0).location();
     if (l == null) return false;
     return resolveCanBeCurrent(
         tr, Utils.getLineForSource(l.declaringType().name(), l.sourceName(), l.lineNumber()));
   } catch (Exception e) {
   }
   return false;
 }
Пример #12
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();
   }
 }
Пример #13
0
  /** Executes breakpoint hit event. */
  public void exec(com.sun.jdi.event.Event ev) {
    // S ystem.out.println ("exec "); // NOI18N
    removeStepRequest();
    StepEvent event = (StepEvent) ev;
    ThreadReference tr = event.thread();
    Location loc = event.location();
    int ln = -1;
    String methodName = "?"; // NOI18N
    String className = "?"; // NOI18N
    String lineNumber = "?"; // NOI18N
    String threadName = tr.name();
    Line l = null;

    if (loc != null) {
      if (loc.method() != null) methodName = loc.method().name();
      className = loc.declaringType().name();
      ln = loc.lineNumber();
      if (ln >= 0) lineNumber = "" + loc.lineNumber();
    }

    if (ln != -1)
      try {
        l = Utils.getLineForSource(className, loc.sourceName(), ln);
      } catch (AbsentInformationException e) {
        l = Utils.getLine(className, ln);
      }

    if (resolveCanBeCurrent(tr, l))
      // if this line can not be current resolveCanBeCurrent () calls stepOver
      return;
    // line can be current

    if ((l == null) && (getLastAction() == ACTION_TRACE_INTO))
      // try to find another "intelligent" line of code
      traceToSourceCode(tr);
    // you know - intelligent means that one with source code
    else {
      makeCurrent(threadName, className, methodName, lineNumber, l != null, tr);
      operator.stopRequest();
    }
  }
Пример #14
0
  public static void removeThread(ThreadReference thread) {
    if (thread.equals(ThreadInfo.current)) {
      // Current thread has died.

      // Be careful getting the thread name. If its death happens
      // as part of VM termination, it may be too late to get the
      // information, and an exception will be thrown.
      String currentThreadName;
      try {
        currentThreadName = "\"" + thread.name() + "\"";
      } catch (Exception e) {
        currentThreadName = "";
      }

      setCurrentThread(null);

      err.println(
          String.format("%s, Current thread died. Execution continuing...", currentThreadName));
    }
    threads.remove(getThreadInfo(thread));
  }
Пример #15
0
  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    if (!super.equals(o)) return false;

    JavaStackFrame that = (JavaStackFrame) o;

    if (myIndex != that.myIndex) return false;
    if (!myThreadReference.equals(that.myThreadReference)) return false;

    return true;
  }
Пример #16
0
 @Override
 public int hashCode() {
   int result = super.hashCode();
   result = 31 * result + myThreadReference.hashCode() * 31 + myIndex;
   return result;
 }
Пример #17
0
  private static List<ThreadState> buildThreadStates(VirtualMachineProxyImpl vmProxy) {
    final List<ThreadReference> threads = vmProxy.getVirtualMachine().allThreads();
    final List<ThreadState> result = new ArrayList<ThreadState>();
    final Map<String, ThreadState> nameToThreadMap = new HashMap<String, ThreadState>();
    final Map<String, String> waitingMap = new HashMap<String, String>(); // key 'waits_for' value
    for (ThreadReference threadReference : threads) {
      final StringBuilder buffer = new StringBuilder();
      boolean hasEmptyStack = true;
      final String threadName = threadName(threadReference);
      final int threadStatus = threadReference.status();
      final ThreadState threadState =
          new ThreadState(threadName, threadStatusToState(threadStatus));
      nameToThreadMap.put(threadName, threadState);
      result.add(threadState);
      threadState.setJavaThreadState(threadStatusToJavaThreadState(threadStatus));

      buffer.append(threadName);
      ReferenceType referenceType = threadReference.referenceType();
      if (referenceType != null) {
        //noinspection HardCodedStringLiteral
        Field daemon = referenceType.fieldByName("daemon");
        if (daemon != null) {
          Value value = threadReference.getValue(daemon);
          if (value instanceof BooleanValue && ((BooleanValue) value).booleanValue()) {
            buffer
                .append(" ")
                .append(DebuggerBundle.message("threads.export.attribute.label.daemon"));
          }
        }

        //noinspection HardCodedStringLiteral
        Field priority = referenceType.fieldByName("priority");
        if (priority != null) {
          Value value = threadReference.getValue(priority);
          if (value instanceof IntegerValue) {
            buffer
                .append(", ")
                .append(
                    DebuggerBundle.message(
                        "threads.export.attribute.label.priority",
                        ((IntegerValue) value).intValue()));
          }
        }
      }

      ThreadGroupReference groupReference = threadReference.threadGroup();
      if (groupReference != null) {
        buffer
            .append(", ")
            .append(
                DebuggerBundle.message(
                    "threads.export.attribute.label.group", groupReference.name()));
      }
      buffer
          .append(", ")
          .append(
              DebuggerBundle.message(
                  "threads.export.attribute.label.status", threadState.getState()));

      buffer.append("\n  java.lang.Thread.State: ").append(threadState.getJavaThreadState());

      try {
        if (vmProxy.canGetOwnedMonitorInfo() && vmProxy.canGetMonitorInfo()) {
          List<ObjectReference> list = threadReference.ownedMonitors();
          for (ObjectReference reference : list) {
            final List<ThreadReference> waiting = reference.waitingThreads();
            for (ThreadReference thread : waiting) {
              final String waitingThreadName = threadName(thread);
              waitingMap.put(waitingThreadName, threadName);
              buffer
                  .append("\n\t ")
                  .append(
                      DebuggerBundle.message(
                          "threads.export.attribute.label.blocks.thread", waitingThreadName));
            }
          }
        }

        ObjectReference waitedMonitor =
            vmProxy.canGetCurrentContendedMonitor()
                ? threadReference.currentContendedMonitor()
                : null;
        if (waitedMonitor != null) {
          if (vmProxy.canGetMonitorInfo()) {
            ThreadReference waitedMonitorOwner = waitedMonitor.owningThread();
            if (waitedMonitorOwner != null) {
              final String monitorOwningThreadName = threadName(waitedMonitorOwner);
              waitingMap.put(threadName, monitorOwningThreadName);
              buffer
                  .append("\n\t ")
                  .append(
                      DebuggerBundle.message(
                          "threads.export.attribute.label.waiting.for.thread",
                          monitorOwningThreadName));
            }
          }
        }

        final List<StackFrame> frames = threadReference.frames();
        hasEmptyStack = frames.size() == 0;
        for (StackFrame stackFrame : frames) {
          final Location location = stackFrame.location();
          buffer.append("\n\t  ").append(renderLocation(location));
        }
      } catch (IncompatibleThreadStateException e) {
        buffer
            .append("\n\t ")
            .append(DebuggerBundle.message("threads.export.attribute.error.incompatible.state"));
      }
      threadState.setStackTrace(buffer.toString(), hasEmptyStack);
      ThreadDumpParser.inferThreadStateDetail(threadState);
    }

    for (String waiting : waitingMap.keySet()) {
      final ThreadState waitingThread = nameToThreadMap.get(waiting);
      final ThreadState awaitedThread = nameToThreadMap.get(waitingMap.get(waiting));
      awaitedThread.addWaitingThread(waitingThread);
    }

    // detect simple deadlocks
    for (ThreadState thread : result) {
      for (ThreadState awaitingThread : thread.getAwaitingThreads()) {
        if (awaitingThread.isAwaitedBy(thread)) {
          thread.addDeadlockedThread(awaitingThread);
          awaitingThread.addDeadlockedThread(thread);
        }
      }
    }

    ThreadDumpParser.sortThreads(result);
    return result;
  }
Пример #18
0
 private static String threadName(ThreadReference threadReference) {
   return threadReference.name() + "@" + threadReference.uniqueID();
 }
Пример #19
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;
  }
Пример #20
0
  /*
   * Complete the construction of an EventSet.  This is called from
   * an event handler thread.  It upacks the JDWP events inside
   * the packet and creates EventImpls for them.  The EventSet is already
   * on EventQueues when this is called, so it has to be synch.
   */
  synchronized void build() {
    if (pkt == null) {
      return;
    }
    PacketStream ps = new PacketStream(vm, pkt);
    JDWP.Event.Composite compEvt = new JDWP.Event.Composite(vm, ps);
    suspendPolicy = compEvt.suspendPolicy;
    if ((vm.traceFlags & vm.TRACE_EVENTS) != 0) {
      switch (suspendPolicy) {
        case JDWP.SuspendPolicy.ALL:
          vm.printTrace("EventSet: SUSPEND_ALL");
          break;

        case JDWP.SuspendPolicy.EVENT_THREAD:
          vm.printTrace("EventSet: SUSPEND_EVENT_THREAD");
          break;

        case JDWP.SuspendPolicy.NONE:
          vm.printTrace("EventSet: SUSPEND_NONE");
          break;
      }
    }

    ThreadReference fix6485605 = null;
    for (int i = 0; i < compEvt.events.length; i++) {
      EventImpl evt = createEvent(compEvt.events[i]);
      if ((vm.traceFlags & vm.TRACE_EVENTS) != 0) {
        try {
          vm.printTrace("Event: " + evt);
        } catch (VMDisconnectedException ee) {
          // ignore - see bug 6502716
        }
      }

      switch (evt.destination()) {
        case UNKNOWN_EVENT:
          // Ignore disabled, deleted, unknown events, but
          // save the thread if there is one since we might
          // have to resume it.  Note that events for different
          // threads can't be in the same event set.
          if (evt instanceof ThreadedEventImpl
              && suspendPolicy == JDWP.SuspendPolicy.EVENT_THREAD) {
            fix6485605 = ((ThreadedEventImpl) evt).thread();
          }
          continue;
        case CLIENT_EVENT:
          addEvent(evt);
          break;
        case INTERNAL_EVENT:
          if (internalEventSet == null) {
            internalEventSet = new EventSetImpl(this.vm, null);
          }
          internalEventSet.addEvent(evt);
          break;
        default:
          throw new InternalException("Invalid event destination");
      }
    }
    pkt = null; // No longer needed - free it up

    // Avoid hangs described in 6296125, 6293795
    if (super.size() == 0) {
      // This set has no client events.  If we don't do
      // needed resumes, no one else is going to.
      if (suspendPolicy == JDWP.SuspendPolicy.ALL) {
        vm.resume();
      } else if (suspendPolicy == JDWP.SuspendPolicy.EVENT_THREAD) {
        // See bug 6485605.
        if (fix6485605 != null) {
          fix6485605.resume();
        } else {
          // apparently, there is nothing to resume.
        }
      }
      suspendPolicy = JDWP.SuspendPolicy.NONE;
    }
  }
Пример #21
0
 public String toString() {
   return eventName() + " in thread " + thread.name();
 }
Пример #22
0
 /* Throw IncompatibleThreadStateException if not suspended */
 private void assureSuspended() throws IncompatibleThreadStateException {
   if (!thread.isSuspended()) {
     throw new IncompatibleThreadStateException();
   }
 }
Пример #23
0
 /**
  * Get the current stackframe.
  *
  * @return the current stackframe.
  */
 public StackFrame getCurrentFrame() throws IncompatibleThreadStateException {
   if (thread.frameCount() == 0) {
     return null;
   }
   return thread.frame(currentFrameIndex);
 }
Пример #24
0
 /**
  * Get the thread stack frames.
  *
  * @return a <code>List</code> of the stack frames.
  */
 List getStack() throws IncompatibleThreadStateException {
   return thread.frames();
 }
  private static List<ThreadState> buildThreadStates(VirtualMachineProxyImpl vmProxy) {
    final List<ThreadReference> threads = vmProxy.getVirtualMachine().allThreads();
    final List<ThreadState> result = new ArrayList<ThreadState>();
    final Map<String, ThreadState> nameToThreadMap = new HashMap<String, ThreadState>();
    final Map<String, String> waitingMap = new HashMap<String, String>(); // key 'waits_for' value
    for (ThreadReference threadReference : threads) {
      final StringBuilder buffer = new StringBuilder();
      boolean hasEmptyStack = true;
      final int threadStatus = threadReference.status();
      if (threadStatus == ThreadReference.THREAD_STATUS_ZOMBIE) {
        continue;
      }
      final String threadName = threadName(threadReference);
      final ThreadState threadState =
          new ThreadState(threadName, threadStatusToState(threadStatus));
      nameToThreadMap.put(threadName, threadState);
      result.add(threadState);
      threadState.setJavaThreadState(threadStatusToJavaThreadState(threadStatus));

      buffer.append("\"").append(threadName).append("\"");
      ReferenceType referenceType = threadReference.referenceType();
      if (referenceType != null) {
        //noinspection HardCodedStringLiteral
        Field daemon = referenceType.fieldByName("daemon");
        if (daemon != null) {
          Value value = threadReference.getValue(daemon);
          if (value instanceof BooleanValue && ((BooleanValue) value).booleanValue()) {
            buffer
                .append(" ")
                .append(DebuggerBundle.message("threads.export.attribute.label.daemon"));
            threadState.setDaemon(true);
          }
        }

        //noinspection HardCodedStringLiteral
        Field priority = referenceType.fieldByName("priority");
        if (priority != null) {
          Value value = threadReference.getValue(priority);
          if (value instanceof IntegerValue) {
            buffer
                .append(" ")
                .append(
                    DebuggerBundle.message(
                        "threads.export.attribute.label.priority",
                        ((IntegerValue) value).intValue()));
          }
        }

        Field tid = referenceType.fieldByName("tid");
        if (tid != null) {
          Value value = threadReference.getValue(tid);
          if (value instanceof LongValue) {
            buffer
                .append(" ")
                .append(
                    DebuggerBundle.message(
                        "threads.export.attribute.label.tid",
                        Long.toHexString(((LongValue) value).longValue())));
            buffer.append(" nid=NA");
          }
        }
      }
      // ThreadGroupReference groupReference = threadReference.threadGroup();
      // if (groupReference != null) {
      //  buffer.append(", ").append(DebuggerBundle.message("threads.export.attribute.label.group",
      // groupReference.name()));
      // }
      final String state = threadState.getState();
      if (state != null) {
        buffer.append(" ").append(state);
      }

      buffer.append("\n  java.lang.Thread.State: ").append(threadState.getJavaThreadState());

      try {
        if (vmProxy.canGetOwnedMonitorInfo() && vmProxy.canGetMonitorInfo()) {
          List<ObjectReference> list = threadReference.ownedMonitors();
          for (ObjectReference reference : list) {
            if (!vmProxy.canGetMonitorFrameInfo()) { // java 5 and earlier
              buffer.append("\n\t ").append(renderLockedObject(reference));
            }
            final List<ThreadReference> waiting = reference.waitingThreads();
            for (ThreadReference thread : waiting) {
              final String waitingThreadName = threadName(thread);
              waitingMap.put(waitingThreadName, threadName);
              buffer
                  .append("\n\t ")
                  .append(
                      DebuggerBundle.message(
                          "threads.export.attribute.label.blocks.thread", waitingThreadName));
            }
          }
        }

        ObjectReference waitedMonitor =
            vmProxy.canGetCurrentContendedMonitor()
                ? threadReference.currentContendedMonitor()
                : null;
        if (waitedMonitor != null) {
          if (vmProxy.canGetMonitorInfo()) {
            ThreadReference waitedMonitorOwner = waitedMonitor.owningThread();
            if (waitedMonitorOwner != null) {
              final String monitorOwningThreadName = threadName(waitedMonitorOwner);
              waitingMap.put(threadName, monitorOwningThreadName);
              buffer
                  .append("\n\t ")
                  .append(
                      DebuggerBundle.message(
                          "threads.export.attribute.label.waiting.for.thread",
                          monitorOwningThreadName,
                          renderObject(waitedMonitor)));
            }
          }
        }

        final List<StackFrame> frames = threadReference.frames();
        hasEmptyStack = frames.size() == 0;

        final TIntObjectHashMap<List<ObjectReference>> lockedAt =
            new TIntObjectHashMap<List<ObjectReference>>();
        if (vmProxy.canGetMonitorFrameInfo()) {
          for (MonitorInfo info : threadReference.ownedMonitorsAndFrames()) {
            final int stackDepth = info.stackDepth();
            List<ObjectReference> monitors;
            if ((monitors = lockedAt.get(stackDepth)) == null) {
              lockedAt.put(stackDepth, monitors = new SmartList<ObjectReference>());
            }
            monitors.add(info.monitor());
          }
        }

        for (int i = 0, framesSize = frames.size(); i < framesSize; i++) {
          final StackFrame stackFrame = frames.get(i);
          try {
            final Location location = stackFrame.location();
            buffer.append("\n\t  ").append(renderLocation(location));

            final List<ObjectReference> monitors = lockedAt.get(i);
            if (monitors != null) {
              for (ObjectReference monitor : monitors) {
                buffer.append("\n\t  - ").append(renderLockedObject(monitor));
              }
            }
          } catch (InvalidStackFrameException e) {
            buffer.append("\n\t  Invalid stack frame: ").append(e.getMessage());
          }
        }
      } catch (IncompatibleThreadStateException e) {
        buffer
            .append("\n\t ")
            .append(DebuggerBundle.message("threads.export.attribute.error.incompatible.state"));
      }
      threadState.setStackTrace(buffer.toString(), hasEmptyStack);
      ThreadDumpParser.inferThreadStateDetail(threadState);
    }

    for (String waiting : waitingMap.keySet()) {
      final ThreadState waitingThread = nameToThreadMap.get(waiting);
      final ThreadState awaitedThread = nameToThreadMap.get(waitingMap.get(waiting));
      awaitedThread.addWaitingThread(waitingThread);
    }

    // detect simple deadlocks
    for (ThreadState thread : result) {
      for (ThreadState awaitingThread : thread.getAwaitingThreads()) {
        if (awaitingThread.isAwaitedBy(thread)) {
          thread.addDeadlockedThread(awaitingThread);
          awaitingThread.addDeadlockedThread(thread);
        }
      }
    }

    ThreadDumpParser.sortThreads(result);
    return result;
  }
Пример #26
0
 public static ThreadInfo getThreadInfo(ThreadReference tr) {
   return getThreadInfo(tr.uniqueID());
 }
Пример #27
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);
    }
  }
Пример #28
0
 /**
  * Get the thread stack frames.
  *
  * @return a <code>List</code> of the stack frames.
  */
 public List<StackFrame> getStack() throws IncompatibleThreadStateException {
   return thread.frames();
 }
Пример #29
0
 public StackFrame getFrameZero(ThreadReference tr) throws IncompatibleThreadStateException {
   return tr.frames().get(0);
 }