public static String renderLocation(final Location location) {
    String sourceName;
    try {
      sourceName = location.sourceName();
    } catch (Throwable e) {
      sourceName = "Unknown Source";
    }

    final StringBuilder methodName = new StringBuilder();
    try {
      methodName.append(location.declaringType().name());
    } catch (Throwable e) {
      methodName.append(e.getMessage());
    }
    methodName.append(".");
    try {
      methodName.append(location.method().name());
    } catch (Throwable e) {
      methodName.append(e.getMessage());
    }

    int lineNumber;
    try {
      lineNumber = location.lineNumber();
    } catch (Throwable e) {
      lineNumber = -1;
    }
    return DebuggerBundle.message(
        "export.threads.stackframe.format", methodName.toString(), sourceName, lineNumber);
  }
  @Override
  public String getEventMessage(LocatableEvent event) {
    final Location location = event.location();
    String sourceName;
    try {
      sourceName = location.sourceName();
    } catch (AbsentInformationException e) {
      sourceName = getFileName();
    }

    final boolean printFullTrace = Registry.is("debugger.breakpoint.message.full.trace");

    StringBuilder builder = new StringBuilder();
    if (printFullTrace) {
      builder.append(
          DebuggerBundle.message(
              "status.line.breakpoint.reached.full.trace",
              DebuggerUtilsEx.getLocationMethodQName(location)));
      try {
        final List<StackFrame> frames = event.thread().frames();
        renderTrace(frames, builder);
      } catch (IncompatibleThreadStateException e) {
        builder.append("Stacktrace not available: ").append(e.getMessage());
      }
    } else {
      builder.append(
          DebuggerBundle.message(
              "status.line.breakpoint.reached",
              DebuggerUtilsEx.getLocationMethodQName(location),
              sourceName,
              getLineIndex() + 1));
    }
    return builder.toString();
  }
Exemple #3
0
 public static String getLocationMethodQName(@NotNull Location location) {
   StringBuilder res = new StringBuilder();
   ReferenceType type = location.declaringType();
   if (type != null) {
     res.append(type.name()).append('.');
   }
   res.append(location.method().name());
   return res.toString();
 }
  private String getDisplayInfoInternal(boolean showPackageInfo, int totalTextLength) {
    if (isValid()) {
      final int lineNumber = myXBreakpoint.getSourcePosition().getLine() + 1;
      String className = getClassName();
      final boolean hasClassInfo = className != null && className.length() > 0;
      final String methodName = getMethodName();
      final String displayName = methodName != null ? methodName + "()" : null;
      final boolean hasMethodInfo = displayName != null && displayName.length() > 0;
      if (hasClassInfo || hasMethodInfo) {
        final StringBuilder info = StringBuilderSpinAllocator.alloc();
        try {
          boolean isFile = myXBreakpoint.getSourcePosition().getFile().getName().equals(className);
          String packageName = null;
          if (hasClassInfo) {
            final int dotIndex = className.lastIndexOf(".");
            if (dotIndex >= 0 && !isFile) {
              packageName = className.substring(0, dotIndex);
              className = className.substring(dotIndex + 1);
            }

            if (totalTextLength != -1) {
              if (className.length() + (hasMethodInfo ? displayName.length() : 0)
                  > totalTextLength + 3) {
                int offset = totalTextLength - (hasMethodInfo ? displayName.length() : 0);
                if (offset > 0 && offset < className.length()) {
                  className = className.substring(className.length() - offset);
                  info.append("...");
                }
              }
            }

            info.append(className);
          }
          if (hasMethodInfo) {
            if (isFile) {
              info.append(":");
            } else if (hasClassInfo) {
              info.append(".");
            }
            info.append(displayName);
          }
          if (showPackageInfo && packageName != null) {
            info.append(" (").append(packageName).append(")");
          }
          return DebuggerBundle.message(
              "line.breakpoint.display.name.with.class.or.method", lineNumber, info.toString());
        } finally {
          StringBuilderSpinAllocator.dispose(info);
        }
      }
      return DebuggerBundle.message("line.breakpoint.display.name", lineNumber);
    }
    return DebuggerBundle.message("status.breakpoint.invalid");
  }
Exemple #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;
  }
  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;
  }
Exemple #7
0
  private Map<String, com.sun.jdi.connect.Connector.Argument> parseConnectorArgs(
      Connector connector, String argString) {
    Map<String, com.sun.jdi.connect.Connector.Argument> arguments = connector.defaultArguments();

    /*
     * We are parsing strings of the form:
     *    name1=value1,[name2=value2,...]
     * However, the value1...valuen substrings may contain
     * embedded comma(s), so make provision for quoting inside
     * the value substrings. (Bug ID 4285874)
     */
    String regexPattern =
        "(quote=[^,]+,)|"
            + // special case for quote=.,
            "(\\w+=)"
            + // name=
            "(((\"[^\"]*\")|"
            + //   ( "l , ue"
            "('[^']*')|"
            + //     'l , ue'
            "([^,'\"]+))+,)"; //     v a l u e )+ ,
    Pattern p = Pattern.compile(regexPattern);
    Matcher m = p.matcher(argString);
    while (m.find()) {
      int startPosition = m.start();
      int endPosition = m.end();
      if (startPosition > 0) {
        /*
         * It is an error if parsing skips over any part of argString.
         */
        throw new IllegalArgumentException(
            MessageOutput.format("Illegal connector argument", argString));
      }

      String token = argString.substring(startPosition, endPosition);
      int index = token.indexOf('=');
      String name = token.substring(0, index);
      String value = token.substring(index + 1, token.length() - 1); // Remove comma delimiter

      /*
       * for values enclosed in quotes (single and/or double quotes)
       * strip off enclosing quote chars
       * needed for quote enclosed delimited substrings
       */
      if (name.equals("options")) {
        StringBuilder sb = new StringBuilder();
        for (String s : splitStringAtNonEnclosedWhiteSpace(value)) {
          while (isEnclosed(s, "\"") || isEnclosed(s, "'")) {
            s = s.substring(1, s.length() - 1);
          }
          sb.append(s);
          sb.append(" ");
        }
        value = sb.toString();
      }

      Connector.Argument argument = arguments.get(name);
      if (argument == null) {
        throw new IllegalArgumentException(
            MessageOutput.format(
                "Argument is not defined for connector:", new Object[] {name, connector.name()}));
      }
      argument.setValue(value);

      argString = argString.substring(endPosition); // Remove what was just parsed...
      m = p.matcher(argString); //    and parse again on what is left.
    }
    if ((!argString.equals(",")) && (argString.length() > 0)) {
      /*
       * It is an error if any part of argString is left over,
       * unless it was empty to begin with.
       */
      throw new IllegalArgumentException(
          MessageOutput.format("Illegal connector argument", argString));
    }
    return arguments;
  }