Search in sources :

Example 6 with JavaMonitor

use of com.ibm.dtfj.java.JavaMonitor in project openj9 by eclipse.

the class DeadlockCommand method doCommand.

public void doCommand() {
    SortedMap monitorNodes = new TreeMap();
    JavaRuntime jr = ctx.getRuntime();
    Iterator itMonitor = jr.getMonitors();
    int nodeListNum = 0;
    out.print("\n  deadlocks for runtime \n");
    // JVM dumps on Linux don't have all the image threads, so we now use JavaThreads
    while (itMonitor.hasNext()) {
        JavaMonitor monitor = (JavaMonitor) itMonitor.next();
        MonitorNode node = new MonitorNode(monitor);
        JavaThread owner = null;
        Long id = null;
        try {
            owner = monitor.getOwner();
        } catch (CorruptDataException e) {
            out.println("exception encountered while getting monitor owner: " + Exceptions.getCorruptDataExceptionString());
            return;
        }
        if (null == owner) {
            // the monitor's owner or the next monitor in a potential deadlock chain.
            continue;
        } else {
            JavaObject threadObject;
            try {
                threadObject = owner.getObject();
            } catch (CorruptDataException e) {
                out.println("exception encountered while getting owner's JavaObject: " + Exceptions.getCorruptDataExceptionString());
                return;
            }
            id = new Long(threadObject.getID().getAddress());
        }
        // Note: defect 133638, we used to give up here with an error if there was already
        // a monitor node in the table with the same key (thread). This is very common (a
        // thread owning multiple monitors). Longer term the intention is to replace this
        // algorithm with the one used in javacore, but for now we carry on to see if we can
        // still find a deadlock, with some node(s) discarded.
        monitorNodes.put(id, node);
    }
    // Step 1.b
    // Add the JUC locks, technically to find all of them you need to walk the whole
    // heap. But the active ones can be found by walking the thread list and looking
    // at the blocking objects. (Any others aren't blocking any threads anyway so aren't
    // interesting.
    Iterator itThread = jr.getThreads();
    while (itThread.hasNext()) {
        try {
            Object o = itThread.next();
            if (!(o instanceof JavaThread)) {
                continue;
            }
            JavaThread jt = (JavaThread) o;
            JavaThread owner = null;
            Long id = null;
            if ((jt.getState() & JavaThread.STATE_PARKED) != 0) {
                JavaObject lock = jt.getBlockingObject();
                MonitorNode node = new JUCMonitorNode(lock, jr);
                try {
                    owner = Utils.getParkBlockerOwner(lock, jr);
                    if (owner == null) {
                        continue;
                    }
                } catch (MemoryAccessException e) {
                    out.println("exception encountered while getting monitor owner: " + Exceptions.getCorruptDataExceptionString());
                    return;
                }
                JavaObject threadObject;
                try {
                    threadObject = owner.getObject();
                } catch (CorruptDataException e) {
                    out.println("exception encountered while getting owner's JavaObject: " + Exceptions.getCorruptDataExceptionString());
                    return;
                }
                id = new Long(threadObject.getID().getAddress());
                monitorNodes.put(id, node);
            }
        } catch (CorruptDataException cde) {
            out.println("\nwarning, corrupt data encountered during scan for java.util.concurrent locks...");
        } catch (DataUnavailable du) {
            out.println("\nwarning, data unavailable encountered during scan for java.util.concurrent locks...");
        }
    }
    Iterator values = monitorNodes.values().iterator();
    // enter waiter, set that waiter's MonitorNode's waitingOn to m1.
    while (values.hasNext()) {
        MonitorNode currNode = (MonitorNode) values.next();
        Iterator itWaiters = currNode.getEnterWaiters();
        while (itWaiters.hasNext()) {
            Object o = itWaiters.next();
            if (!(o instanceof JavaThread)) {
                continue;
            }
            JavaThread waiter = (JavaThread) o;
            JavaObject threadObject;
            Long id = null;
            try {
                threadObject = waiter.getObject();
            } catch (CorruptDataException e) {
                out.println("exception encountered while getting waiter's ImageThread: " + Exceptions.getCorruptDataExceptionString());
                return;
            }
            id = new Long(threadObject.getID().getAddress());
            MonitorNode waiterNode = (MonitorNode) monitorNodes.get(id);
            if (null != waiterNode) {
                waiterNode.waitingOn = currNode;
            }
        }
    }
    values = monitorNodes.values().iterator();
    int visit = 1;
    Vector lists = new Vector();
    while (values.hasNext()) {
        MonitorNode startNode = (MonitorNode) values.next();
        MonitorNode currNode = startNode;
        MonitorNode endNode;
        if (0 != startNode.visit) {
            continue;
        }
        while (true) {
            currNode.visit = visit;
            if (null == currNode.waitingOn) {
                currNode.deadlock = MonitorNode.NO_DEADLOCK;
                break;
            }
            if (isDeadlocked(currNode.waitingOn)) {
                // we've encountered a deadlocked node in the chain;
                // set branch deadlock for all nodes between startNode
                // and currNode
                endNode = currNode.waitingOn;
                currNode = startNode;
                NodeList branchList = null;
                while (currNode != endNode) {
                    if (null == branchList) {
                        branchList = new NodeList(currNode, nodeListNum++);
                    }
                    currNode.deadlock = MonitorNode.BRANCH_DEADLOCK;
                    currNode = currNode.waitingOn;
                    branchList.add(currNode);
                    if (currNode != endNode)
                        currNode.inList = branchList;
                }
                if (endNode.inList.isLoop()) {
                    lists.insertElementAt(branchList, lists.indexOf(endNode.inList));
                } else {
                    NodeList oldList = endNode.inList;
                    // FIXME: the below line will cause problems with at least
                    // one case that was not considered when attachOrSplit was
                    // coded: if a NodeList n1 has already been split and another
                    // NodeList n2 tries to attach to the end of n1, then n1 will
                    // allow n2 to attach to n1, while what n1 should really do is
                    // just return n2 and not allow n2 to attach to itself
                    NodeList split = endNode.inList.attachOrSplit(branchList, nodeListNum++);
                    if (null != split) {
                        lists.insertElementAt(split, lists.indexOf(oldList));
                        lists.insertElementAt(branchList, lists.indexOf(oldList));
                    }
                }
                break;
            }
            if (currNode.waitingOn.visit == visit) {
                // we've encountered a node in the same visit as the current
                // visit, ie. we've found a loop; first flag the whole loop
                // with a loop deadlock flag, then flag the rest of the nodes
                // in the chain with a branch deadlock
                endNode = currNode.waitingOn;
                currNode = endNode;
                NodeList loopList = new NodeList(currNode, nodeListNum++);
                lists.insertElementAt(loopList, 0);
                do {
                    currNode.deadlock = MonitorNode.LOOP_DEADLOCK;
                    currNode = currNode.waitingOn;
                    loopList.add(currNode);
                    currNode.inList = loopList;
                } while (currNode != endNode);
                currNode = startNode;
                NodeList branchList = null;
                while (currNode != endNode) {
                    if (null == branchList) {
                        branchList = new NodeList(currNode, nodeListNum++);
                        lists.insertElementAt(branchList, 0);
                    }
                    currNode.deadlock = MonitorNode.BRANCH_DEADLOCK;
                    currNode = currNode.waitingOn;
                    branchList.add(currNode);
                    if (currNode != endNode)
                        currNode.inList = branchList;
                }
                break;
            }
            currNode = currNode.waitingOn;
        }
        visit++;
    }
    if (lists.isEmpty()) {
        out.print("\n");
        out.print("\t no deadlocks detected");
        out.print("\n");
        return;
    }
    boolean lastListWasLoop = true;
    Iterator itList = lists.iterator();
    // Step 5. print the lists
    while (itList.hasNext()) {
        NodeList list = (NodeList) itList.next();
        if (list.isLoop()) {
            out.print("\n    deadlock loop:\n");
            lastListWasLoop = true;
        } else if (lastListWasLoop) {
            // && !list.isLoop()
            out.print("\n\n    deadlock branch(es):\n");
            lastListWasLoop = false;
        }
        out.print("\t  " + list.toString());
        out.print("\n");
    }
    out.print("\n");
}
Also used : JavaRuntime(com.ibm.dtfj.java.JavaRuntime) NodeList(com.ibm.jvm.dtfjview.commands.helpers.NodeList) CorruptDataException(com.ibm.dtfj.image.CorruptDataException) TreeMap(java.util.TreeMap) JUCMonitorNode(com.ibm.jvm.dtfjview.commands.helpers.JUCMonitorNode) JavaMonitor(com.ibm.dtfj.java.JavaMonitor) JUCMonitorNode(com.ibm.jvm.dtfjview.commands.helpers.JUCMonitorNode) MonitorNode(com.ibm.jvm.dtfjview.commands.helpers.MonitorNode) JavaObject(com.ibm.dtfj.java.JavaObject) SortedMap(java.util.SortedMap) Iterator(java.util.Iterator) JavaThread(com.ibm.dtfj.java.JavaThread) DataUnavailable(com.ibm.dtfj.image.DataUnavailable) JavaObject(com.ibm.dtfj.java.JavaObject) MemoryAccessException(com.ibm.dtfj.image.MemoryAccessException) Vector(java.util.Vector)

Example 7 with JavaMonitor

use of com.ibm.dtfj.java.JavaMonitor in project openj9 by eclipse.

the class InfoLockCommand method showSystemLocks.

private void showSystemLocks() {
    Vector vMonitorsWithLockedObjects = new Vector();
    JavaRuntime jRuntime = ctx.getRuntime();
    Iterator monitors = jRuntime.getMonitors();
    out.println("\nSystem locks...");
    while (monitors.hasNext()) {
        JavaMonitor jMonitor = (JavaMonitor) monitors.next();
        JavaObject jObject = jMonitor.getObject();
        try {
            String monitorName = jMonitor.getName().trim();
            if (monitorName.equalsIgnoreCase("")) {
                monitorName = "<un-named monitor>";
            }
            out.println("id: 0x" + jMonitor.getID() + " name: " + jMonitor.getName());
            JavaThread owner = jMonitor.getOwner();
            if (null != owner) {
                try {
                    out.println("\towner thread id: " + owner.getImageThread().getID() + " name: " + owner.getName());
                } catch (DataUnavailable e) {
                    out.println("\towner thread id: " + Exceptions.getDataUnavailableString());
                    logger.log(Level.FINE, Exceptions.getDataUnavailableString(), e);
                }
            }
            showWaiters(jMonitor);
        } catch (CorruptDataException cde) {
            out.println("\nwarning, corrupt data encountered during scan for system locks...");
        }
        if (null != jObject) {
            // Remember object monitors (flat or inflated) for later
            vMonitorsWithLockedObjects.add(jMonitor);
        }
    }
    showLockedObjects(vMonitorsWithLockedObjects);
}
Also used : JavaRuntime(com.ibm.dtfj.java.JavaRuntime) JavaObject(com.ibm.dtfj.java.JavaObject) Iterator(java.util.Iterator) JavaThread(com.ibm.dtfj.java.JavaThread) DataUnavailable(com.ibm.dtfj.image.DataUnavailable) CorruptDataException(com.ibm.dtfj.image.CorruptDataException) Vector(java.util.Vector) JavaMonitor(com.ibm.dtfj.java.JavaMonitor)

Example 8 with JavaMonitor

use of com.ibm.dtfj.java.JavaMonitor in project openj9 by eclipse.

the class InfoLockCommand method showLockedObjects.

private void showLockedObjects(Vector vMonitorsWithLockedObjects) {
    out.println("\nObject Locks in use...");
    if (0 == vMonitorsWithLockedObjects.size()) {
        out.println("\t...None.");
        return;
    }
    Iterator lockedObjects = vMonitorsWithLockedObjects.iterator();
    while (lockedObjects.hasNext()) {
        JavaMonitor jMonitor = (JavaMonitor) lockedObjects.next();
        JavaObject jObject = jMonitor.getObject();
        try {
            JavaThread owner = jMonitor.getOwner();
            String className = "<unknown class>";
            JavaClass jClass = jObject.getJavaClass();
            if (null != jClass) {
                className = jClass.getName();
            }
            String jObjectID = Long.toHexString(jObject.getID().getAddress());
            if (null == owner) {
                out.println(className + "@0x" + jObjectID);
            } else {
                String owningThreadID = null;
                try {
                    owningThreadID = owner.getImageThread().getID();
                } catch (DataUnavailable e) {
                    owningThreadID = Exceptions.getDataUnavailableString();
                }
                out.println(className + "@0x" + jObjectID);
                out.println("\towner thread id: " + owningThreadID + " name: " + owner.getName());
            }
            showWaiters(jMonitor);
        } catch (CorruptDataException cde) {
            logger.log(Level.FINE, Exceptions.getCorruptDataExceptionString(), cde);
        }
    }
}
Also used : JavaObject(com.ibm.dtfj.java.JavaObject) JavaClass(com.ibm.dtfj.java.JavaClass) Iterator(java.util.Iterator) JavaThread(com.ibm.dtfj.java.JavaThread) DataUnavailable(com.ibm.dtfj.image.DataUnavailable) CorruptDataException(com.ibm.dtfj.image.CorruptDataException) JavaMonitor(com.ibm.dtfj.java.JavaMonitor)

Aggregations

JavaMonitor (com.ibm.dtfj.java.JavaMonitor)8 JavaThread (com.ibm.dtfj.java.JavaThread)6 Iterator (java.util.Iterator)6 JavaObject (com.ibm.dtfj.java.JavaObject)5 CorruptDataException (com.ibm.dtfj.image.CorruptDataException)4 DataUnavailable (com.ibm.dtfj.image.DataUnavailable)3 CorruptData (com.ibm.dtfj.image.CorruptData)2 JavaClass (com.ibm.dtfj.java.JavaClass)2 JavaRuntime (com.ibm.dtfj.java.JavaRuntime)2 Vector (java.util.Vector)2 MemoryAccessException (com.ibm.dtfj.image.MemoryAccessException)1 JavaClassLoader (com.ibm.dtfj.java.JavaClassLoader)1 JavaObject (com.ibm.dtfj.java.j9.JavaObject)1 JUCMonitorNode (com.ibm.jvm.dtfjview.commands.helpers.JUCMonitorNode)1 MonitorNode (com.ibm.jvm.dtfjview.commands.helpers.MonitorNode)1 MonitorState (com.ibm.jvm.dtfjview.commands.helpers.MonitorState)1 NodeList (com.ibm.jvm.dtfjview.commands.helpers.NodeList)1 StateToString (com.ibm.jvm.dtfjview.commands.helpers.StateToString)1 SortedMap (java.util.SortedMap)1 TreeMap (java.util.TreeMap)1