예제 #1
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.");
     }
   }
 }
예제 #2
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();
  }
예제 #3
0
 private void commandThreadGroups() throws NoSessionException {
   ThreadGroupIterator it = allThreadGroups();
   int cnt = 0;
   OutputSink out = env.getOutputSink();
   while (it.hasNext()) {
     ThreadGroupReference tg = it.nextThreadGroup();
     ++cnt;
     out.println("" + cnt + ". " + Utils.description(tg) + " " + tg.name());
   }
   out.show();
 }
예제 #4
0
 private ThreadGroupReference findThreadGroup(String name) throws NoSessionException {
   // ### Issue: Uniqueness of thread group names is not enforced.
   ThreadGroupIterator tgi = allThreadGroups();
   while (tgi.hasNext()) {
     ThreadGroupReference tg = tgi.nextThreadGroup();
     if (tg.name().equals(name)) {
       return tg;
     }
   }
   return null;
 }
예제 #5
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;
  }