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