public char[] declaringTypeName() {
   if (this.breakpointLine != Integer.MAX_VALUE) { // if not in a code snippet
     StackFrame frame = getStackFrame();
     return frame.location().declaringType().name().toCharArray();
   }
   return null;
 }
 public boolean isStatic() {
   if (this.breakpointLine != Integer.MAX_VALUE) { // if not in a code snippet
     StackFrame frame = getStackFrame();
     return frame.location().method().isStatic();
   }
   return false;
 }
Example #3
0
    @Override
    public Component getListCellRendererComponent(
        JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {

      // ### We should indicate the current thread independently of the
      // ### selection, e.g., with an icon, because the user may change
      // ### the selection graphically without affecting the current
      // ### thread.

      super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
      if (value == null) {
        this.setText("<unavailable>");
      } else {
        StackFrame frame = (StackFrame) value;
        Location loc = frame.location();
        Method meth = loc.method();
        String methName = meth.declaringType().name() + '.' + meth.name();
        String position = "";
        if (meth.isNative()) {
          position = " (native method)";
        } else if (loc.lineNumber() != -1) {
          position = ":" + loc.lineNumber();
        } else {
          long pc = loc.codeIndex();
          if (pc != -1) {
            position = ", pc = " + pc;
          }
        }
        // Indices are presented to the user starting from 1, not 0.
        this.setText("[" + (index + 1) + "] " + methName + position);
      }
      return this;
    }
  public boolean isVisible(StackFrame frame) {
    validateMirror(frame);
    Method frameMethod = frame.location().method();

    if (!frameMethod.equals(method)) {
      throw new IllegalArgumentException("frame method different than variable's method");
    }

    // this is here to cover the possibility that we will
    // allow LocalVariables for native methods.  If we do
    // so we will have to re-examinine this.
    if (frameMethod.isNative()) {
      return false;
    }

    return ((scopeStart.compareTo(frame.location()) <= 0)
        && (scopeEnd.compareTo(frame.location()) >= 0));
  }
Example #5
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();
   }
 }
Example #6
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();
   }
 }
Example #7
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;
  }
Example #8
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;
  }
  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 static void renderTrace(List<StackFrame> frames, StringBuilder buffer) {
   for (final StackFrame stackFrame : frames) {
     final Location location = stackFrame.location();
     buffer.append("\n\t  ").append(ThreadDumpAction.renderLocation(location));
   }
 }
Example #11
0
 @Override
 public JavaLocation getLocation() {
   StackFrame stackFrame = getStackFrame();
   if (stackFrame == null) return null;
   return new JavaLocation(stackFrame.location());
 }