public ElementInfo getBlockedObject(ThreadInfo th, boolean isBeforeCall) { int objref; ElementInfo ei = null; if (isSynchronized()) { if (isStatic()) { objref = ci.getClassObjectRef(); } else { // NOTE 'inMethod' doesn't work for natives, because th.getThis() // pulls 'this' from the stack frame, which we don't have (and don't need) // for natives objref = isBeforeCall ? th.getCalleeThis(this) : th.getThis(); } ei = th.getElementInfo(objref); assert (ei != null) : ("inconsistent stack, no object or class ref: " + getCompleteName() + " (" + objref + ")"); } return ei; }
@Override public void terminateProcess(ThreadInfo ti) { SystemState ss = getSystemState(); ThreadInfo[] liveThreads = getLiveThreads(); ThreadInfo finalizerTi = null; for (int i = 0; i < liveThreads.length; i++) { if (!liveThreads[i].isSystemThread()) { // keep the stack frames around, so that we can inspect the snapshot liveThreads[i].setTerminated(); } else { // FinalizerThread is not killed at this point. We need to keep it around in // case fianlizable objects are GCed after System.exit() returns. finalizerTi = liveThreads[i]; } } ss.setMandatoryNextChoiceGenerator( new BreakGenerator("exit", ti, true), "exit without break CG"); // if there is a finalizer thread, we have to run the last GC, to queue finalizable objects, if // any if (finalizerTi != null) { assert finalizerTi.isAlive(); activateGC(); } }
@Override public ApplicationContext getCurrentApplicationContext() { ThreadInfo ti = ThreadInfo.getCurrentThread(); if (ti != null) { return ti.getApplicationContext(); } else { return appCtx; } }
public static void main(String[] argv) throws Exception { mbean = newPlatformMXBeanProxy(server, THREAD_MXBEAN_NAME, ThreadMXBean.class); if (!mbean.isSynchronizerUsageSupported()) { System.out.println("Monitoring of synchronizer usage not supported"); return; } thread.setDaemon(true); thread.start(); // wait until myThread acquires mutex and lock owner is set. while (!(mutex.isLocked() && mutex.getLockOwner() == thread)) { try { Thread.sleep(100); } catch (InterruptedException e) { throw new RuntimeException(e); } } long[] ids = new long[] {thread.getId()}; // validate the local access ThreadInfo[] infos = getThreadMXBean().getThreadInfo(ids, true, true); if (infos.length != 1) { throw new RuntimeException( "Returned ThreadInfo[] of length=" + infos.length + ". Expected to be 1."); } thread.checkThreadInfo(infos[0]); // validate the remote access infos = mbean.getThreadInfo(ids, true, true); if (infos.length != 1) { throw new RuntimeException( "Returned ThreadInfo[] of length=" + infos.length + ". Expected to be 1."); } thread.checkThreadInfo(infos[0]); boolean found = false; infos = mbean.dumpAllThreads(true, true); for (ThreadInfo ti : infos) { if (ti.getThreadId() == thread.getId()) { thread.checkThreadInfo(ti); found = true; } } if (!found) { throw new RuntimeException("No ThreadInfo found for MyThread"); } System.out.println("Test passed"); }
/* * puts the twoThreadInfo object into its appropriate spot based on which thread is specified (O or 1) */ private void organize(TwoThreadInfo twoThreadInfo, int i) { ThreadInfo threadInfo; if (i == 0) { threadInfo = twoThreadInfo.getThreadInfo0(); } else { threadInfo = twoThreadInfo.getThreadInfo1(); } try { // we find out where in the data structure to put it, and initialize that element if needed, // then put it in there. final int block = threadInfo.getBlock(); final int thread = threadInfo.getThread(); final int warp = thread / threadsPerWarp; if (blocks.containsKey(block)) { final Map<Integer, Map<Integer, List<TwoThreadInfo>>> warps = blocks.get(block); if (warps.containsKey(warp)) { final Map<Integer, List<TwoThreadInfo>> threads = warps.get(warp); if (threads.containsKey(thread)) { final List<TwoThreadInfo> threadInfos = threads.get(thread); threadInfos.add(twoThreadInfo); } else { final List<TwoThreadInfo> threadInfos = new ArrayList<TwoThreadInfo>(); threadInfos.add(twoThreadInfo); threads.put(thread, threadInfos); } } else { final Map<Integer, List<TwoThreadInfo>> threads = new HashMap<Integer, List<TwoThreadInfo>>(); final List<TwoThreadInfo> threadInfos = new ArrayList<TwoThreadInfo>(); threadInfos.add(twoThreadInfo); threads.put(thread, threadInfos); warps.put(warp, threads); } } else { final Map<Integer, Map<Integer, List<TwoThreadInfo>>> warps = new HashMap<Integer, Map<Integer, List<TwoThreadInfo>>>(); final Map<Integer, List<TwoThreadInfo>> threads = new HashMap<Integer, List<TwoThreadInfo>>(); final List<TwoThreadInfo> threadInfos = new ArrayList<TwoThreadInfo>(); threadInfos.add(twoThreadInfo); threads.put(thread, threadInfos); warps.put(warp, threads); blocks.put(block, warps); } } catch (final NumberFormatException nfe) { /* * Just ignore this improperly formatted ThreadInfo object (not all of them are "properly" formatted after all--example: * deadlock doesn't specify two threads) */ } }
private void enter(ThreadInfo ti) { if (isSynchronized()) { ElementInfo ei = getBlockedObject(ti, true); ei.lock(ti); if (isStatic() && isClinit()) { ci.setInitializing(ti); } } StackFrame frame = new StackFrame(this, ti.getTopFrame()); ti.pushFrame(frame); ti.getVM().notifyMethodEntered(ti, this); }
/** * A total hack to see if there are any active Java3D threads running * * @return any java3d threads running */ private static boolean anyJava3dThreadsActive() { ThreadMXBean threadBean = ManagementFactory.getThreadMXBean(); long[] ids = threadBean.getAllThreadIds(); for (int i = 0; i < ids.length; i++) { ThreadInfo info = threadBean.getThreadInfo(ids[i], Integer.MAX_VALUE); if (info == null) { continue; } if (info.getThreadState() != Thread.State.RUNNABLE) { continue; } if (info.getThreadName().indexOf("J3D") >= 0) { return true; } } return false; }
@Override public int getSize() { try { return tinfo == null ? 1 : tinfo.getFrameCount(); } catch (VMNotInterruptedException e) { // ### Is this the right way to handle this? return 0; } }
// @Override public boolean checkUpdatedSharedness(ThreadInfo ti) { if (refTid == null) { refTid = createRefTid(ti.getId()); attributes |= ElementInfo.ATTR_REFTID_CHANGED; return true; } else { return super.checkUpdatedSharedness(ti); } }
@Override public boolean isDeadlocked() { boolean hasNonDaemons = false; boolean hasBlockedThreads = false; if (ss.isBlockedInAtomicSection()) { return true; // blocked in atomic section } ThreadInfo[] threads = getThreadList().getThreads(); boolean hasUserThreads = false; for (int i = 0; i < threads.length; i++) { ThreadInfo ti = threads[i]; if (ti.isAlive()) { hasNonDaemons |= !ti.isDaemon(); // shortcut - if there is at least one runnable, we are not deadlocked if (ti.isTimeoutRunnable()) { // willBeRunnable() ? return false; } if (!ti.isSystemThread()) { hasUserThreads = true; } // means it is not NEW or TERMINATED, i.e. live & blocked hasBlockedThreads = true; } } boolean isDeadlock = hasNonDaemons && hasBlockedThreads; if (processFinalizers && isDeadlock && !hasUserThreads) { // all threads are blocked, system threads. If the finalizer thread // is in-use, then this is a deadlocked state. return (!getFinalizerThread().isIdle()); } return isDeadlock; }
public static void main(String[] args) throws Exception { // TODO Auto-generated method stub if (args.length != 4) { System.err.println("Please provide process id zabbix-host zabbix-port host-guid"); System.exit(-1); } String processPid = args[0]; String zabbixHost = args[1]; String zabbixPort = args[2]; String hostGuid = args[3]; VirtualMachine vm = VirtualMachine.attach(processPid); String connectorAddr = vm.getAgentProperties().getProperty("com.sun.management.jmxremote.localConnectorAddress"); if (connectorAddr == null) { String agent = vm.getSystemProperties().getProperty("java.home") + File.separator + "lib" + File.separator + "management-agent.jar"; vm.loadAgent(agent); connectorAddr = vm.getAgentProperties().getProperty("com.sun.management.jmxremote.localConnectorAddress"); } JMXServiceURL serviceURL = new JMXServiceURL(connectorAddr); JMXConnector connector = JMXConnectorFactory.connect(serviceURL); MBeanServerConnection mbsc = connector.getMBeanServerConnection(); ObjectName objName = new ObjectName(ManagementFactory.THREAD_MXBEAN_NAME); Set<ObjectName> mbeans = mbsc.queryNames(objName, null); for (ObjectName name : mbeans) { ThreadMXBean threadBean; threadBean = ManagementFactory.newPlatformMXBeanProxy(mbsc, name.toString(), ThreadMXBean.class); long threadIds[] = threadBean.getAllThreadIds(); for (long threadId : threadIds) { ThreadInfo threadInfo = threadBean.getThreadInfo(threadId); System.out.println(threadInfo.getThreadName() + " / " + threadInfo.getThreadState()); } } }
@Override public Object getElementAt(int index) { try { return tinfo == null ? null : tinfo.getFrame(index); } catch (VMNotInterruptedException e) { // ### Is this the right way to handle this? // ### Would happen if user scrolled stack trace // ### while not interrupted -- should probably // ### block user interaction in this case. return null; } }
/* * Sets up the node for a threadTree item */ private void setupThreadInfoLeaf( TreeItem twoThreadTree, ThreadInfo threadInfo, IProject project) { try { final String label = threadInfo.getLabel(project); final TreeItem leaf = new TreeItem(twoThreadTree, SWT.NONE); leaf.setText(label); // connect the leaf with the data so that it can be accessed on double click leaf.setData(threadInfo); } catch (final NumberFormatException nfe) { // the getLabel may throw this exception for items that don't have info for both threads } }
/** * 将原始数据切割后装入ThreadInfo,并以Key=WaitID,Value= ThreadInfo实体放入到Multimap<String, ThreadInfo>集合中 * ps:Multimap 类似于Map<key,collection>, key:value-> 1:n * * @param rawDatas * @return */ public Multimap<String, ThreadInfo> getThreadInfo(List<String[]> rawDatas) { Multimap<String, ThreadInfo> w_IdMap = HashMultimap.create(); List<ThreadInfo> threadsList = Lists.newArrayList(); for (String[] rawData : rawDatas) { ThreadInfo threadInfo = new ThreadInfo(); Pattern t_id = Pattern.compile("tid=(0x[\\d\\w]+)"); Pattern t_name = Pattern.compile("\"([\\d\\D]*)\""); Pattern w_Id = Pattern.compile("\\[(0x[\\d\\w]+)\\]"); Matcher tIdMatcher = t_id.matcher(rawData[0]); Matcher nameMatcher = t_name.matcher(rawData[0]); Matcher w_IdMatcher = w_Id.matcher(rawData[0]); if (tIdMatcher.find()) { threadInfo.setThreadId(tIdMatcher.group(1)); } if (nameMatcher.find()) { threadInfo.setThreadName(nameMatcher.group(1)); } if (w_IdMatcher.find()) { threadInfo.setWaitThreadId(w_IdMatcher.group(1)); } threadInfo.setThreadCondition(rawData[1]); w_IdMap.put(threadInfo.getWaitThreadId(), threadInfo); } return w_IdMap; }
void checkThreadInfo(ThreadInfo info) { if (!getName().equals(info.getThreadName())) { throw new RuntimeException( "Name: " + info.getThreadName() + " not matched. Expected: " + getName()); } MonitorInfo[] monitors = info.getLockedMonitors(); if (monitors.length != OWNED_MONITORS) { throw new RuntimeException( "Number of locked monitors = " + monitors.length + " not matched. Expected: " + OWNED_MONITORS); } MonitorInfo m = monitors[0]; StackTraceElement ste = m.getLockedStackFrame(); int depth = m.getLockedStackDepth(); StackTraceElement[] stacktrace = info.getStackTrace(); if (!ste.equals(stacktrace[depth])) { System.out.println("LockedStackFrame:- " + ste); System.out.println("StackTrace at " + depth + " :-" + stacktrace[depth]); throw new RuntimeException( "LockedStackFrame does not match " + "stack frame in ThreadInfo.getStackTrace"); } String className = lock.getClass().getName(); int hcode = System.identityHashCode(lock); if (!className.equals(m.getClassName()) || hcode != m.getIdentityHashCode() || !m.getLockedStackFrame().getMethodName().equals("run")) { System.out.println(info); throw new RuntimeException("MonitorInfo " + m + " doesn't match."); } LockInfo[] syncs = info.getLockedSynchronizers(); if (syncs.length != OWNED_SYNCS) { throw new RuntimeException( "Number of locked syncs = " + syncs.length + " not matched. Expected: " + OWNED_SYNCS); } AbstractOwnableSynchronizer s = mutex.getSync(); String lockName = s.getClass().getName(); hcode = System.identityHashCode(s); if (!lockName.equals(syncs[0].getClassName())) { throw new RuntimeException( "LockInfo : " + syncs[0] + " class name not matched. Expected: " + lockName); } if (hcode != syncs[0].getIdentityHashCode()) { throw new RuntimeException( "LockInfo: " + syncs[0] + " IdentityHashCode not matched. Expected: " + hcode); } LockInfo li = info.getLockInfo(); if (li == null) { throw new RuntimeException("Expected non-null LockInfo"); } }
private static void printThreadInfo(CompositeData cd) { ThreadInfo info = ThreadInfo.from(cd); if (info == null) { throw new RuntimeException("TEST FAILED: " + " Null ThreadInfo"); } System.out.print(info.getThreadName()); System.out.print(" id=" + info.getThreadId()); System.out.println(" " + info.getThreadState()); for (StackTraceElement s : info.getStackTrace()) { System.out.println(s); } }
/** execute this method, which might be either bytecode or native. */ public Instruction execute(ThreadInfo ti) { if (((attrs & MJI_NATIVE) != 0) || isNative()) { NativePeer nativePeer = ci.getNativePeer(); if (nativePeer != null) { JVM vm = ti.getVM(); StackFrame frame = new StackFrame(this, ti.getTopFrame()); // since there is no enter/leave for native methods, we have to do // the notifications explicitly ti.pushFrame(frame); // Make the logic easier in listeners (e.g. vm.getLastMethod() == // vm.getCurrentThread().getMethod()) vm.notifyMethodEntered(ti, this); ti.popFrame( false); // Can't keep the frame for later in this method since nativePeer.executeMethod // will do work on the top of the stack // <2do> Allow for the frame to remain on the stack for the duration of the call to // nativePeer.executeMethod(). Instruction nextInsn = nativePeer.executeMethod(ti, this); ti.pushFrame(frame); // Make the logic easier in listeners (e.g. vm.getLastMethod() == // vm.getCurrentThread().getMethod()) vm.notifyMethodExited(ti, this); ti.popFrame(false); // Can't keep the frame since we don't want to leak frames. return nextInsn; } else { return ti.createAndThrowException( "java.lang.UnsatisfiedLinkError", ci.getName() + '.' + getUniqueName() + " (no peer)"); } } else { enter(ti); return ti.getPC(); } }
public void leave(ThreadInfo ti) { // <2do> - that's not really enough, we might have suspicious bytecode that fails // to release locks acquired by monitor_enter (e.g. by not having a handler that // monitor_exits & re-throws). That's probably shifted into the bytecode verifier // in the future (i.e. outside JPF), but maybe we should add an explicit test here // and report an error if the code does asymmetric locking (according to the specs, // VMs are allowed to silently fix this, so it might run on some and fail on others) if (isSynchronized()) { ElementInfo ei = getBlockedObject(ti, false); ei.unlock(ti); if (isStatic() && isClinit()) { // we just released the lock on the class object, returning from a clinit // now we can consider this class to be initialized. // NOTE this is still part of the RETURN insn of clinit, so ClassInfo.isInitialized // is protected ci.setInitialized(); } } ti.getVM().notifyMethodExited(ti, this); }
public boolean isThreadEntry(ThreadInfo ti) { return (uniqueName.equals("run()V") && (ti.countStackFrames() == 1)); }