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(); }
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"); }
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; }
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; }