use of com.ibm.dtfj.java.JavaThread in project openj9 by eclipse.
the class JavaMonitor method getOwner.
/* (non-Javadoc)
* @see com.ibm.dtfj.java.JavaMonitor#getOwner()
*/
public JavaThread getOwner() throws CorruptDataException {
JavaThread owningThread = null;
Iterator allThreads = _javaVM.getThreads();
while (allThreads.hasNext()) {
JavaThread oneThread = (JavaThread) allThreads.next();
if (oneThread.getJNIEnv().getAddress() == _owningThreadID) {
owningThread = oneThread;
break;
}
}
if ((null == owningThread) && (0 != _owningThreadID)) {
// we have an owner but we couldn't find it. That implies that the XML is corrupt
throw new CorruptDataException(new CorruptData("Monitor owner not found", _javaVM.pointerInAddressSpace(_owningThreadID)));
}
return owningThread;
}
use of com.ibm.dtfj.java.JavaThread in project openj9 by eclipse.
the class ThreadSectionParser method processThreadandStackTrace.
/**
* @param javaThreadResults
* @param buildModel
* @param currentThread Is this the current thread?
* @param currentLineNumber
* @return updated line number
* @throws ParserException
*/
protected int processThreadandStackTrace(IAttributeValueMap javaThreadResults, boolean buildModel, boolean currentThread, int currentLineNumber) throws ParserException {
JavaThread javaThread = null;
// 3XMTHREADINFO1 found only in J9 2.4 or higher. Native thread ID is contained
// in the latter. For all other older VMs, native thread ID is contained in 3XMTHREADINFO
IAttributeValueMap nativeResults = processTagLineOptional(T_3XMTHREADINFO1);
IAttributeValueMap nativeStack;
ArrayList nativeStacks = new ArrayList();
while ((nativeStack = processTagLineOptional(T_3XMTHREADINFO2)) != null) {
nativeStacks.add(nativeStack);
}
IAttributeValueMap blockerInfo = processTagLineOptional(T_3XMTHREADBLOCK);
IAttributeValueMap cpuTimes = processTagLineOptional(T_3XMCPUTIME);
if (buildModel) {
javaThread = addThread(javaThreadResults, nativeResults, nativeStacks, blockerInfo, cpuTimes, currentLineNumber);
}
long imageThreadID = (nativeResults != null) ? nativeResults.getLongValue(NATIVE_THREAD_ID) : javaThreadResults.getLongValue(NATIVE_THREAD_ID);
long tid = javaThreadResults.getLongValue(VM_THREAD_ID);
if (imageThreadID == IBuilderData.NOT_AVAILABLE) {
imageThreadID = tid;
}
parseStackTrace(javaThread, currentLineNumber, buildModel);
parseNativeStackTrace(imageThreadID, buildModel);
if (currentThread) {
// Indicate we have a possible current thread
fImageProcessBuilder.setCurrentThreadID(imageThreadID);
}
return getCurrentFileLineNumber();
}
use of com.ibm.dtfj.java.JavaThread in project openj9 by eclipse.
the class PHDJavaRuntime method prepThreads.
/**
* Remember objects associated with threads.
* Performance optimization - we can then find these objects on a scan through the heap
* and remember them, saving a fruitless search of the heap if they only exist in a javacore.
*/
private void prepThreads() {
if (metaJavaRuntime != null) {
final PHDJavaClassLoader boot = loaders.get(null);
for (Iterator it = metaJavaRuntime.getThreads(); it.hasNext(); ) {
Object next = it.next();
if (next instanceof CorruptData)
continue;
JavaThread thr = (JavaThread) next;
try {
JavaObject jo = thr.getObject();
saveExtraObject(boot, jo);
} catch (CorruptDataException e) {
}
}
}
}
use of com.ibm.dtfj.java.JavaThread 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.JavaThread in project openj9 by eclipse.
the class JUCMonitorNode method getEnterWaiters.
public Iterator getEnterWaiters() {
List waiters = new LinkedList();
Iterator itThread = jr.getThreads();
while (itThread.hasNext()) {
Object o = itThread.next();
try {
if (!(o instanceof JavaThread)) {
continue;
}
JavaThread jt = (JavaThread) o;
if ((jt.getState() & JavaThread.STATE_PARKED) != 0) {
JavaObject blocker = jt.getBlockingObject();
if (blocker != null && blocker.equals(lock)) {
waiters.add(jt);
}
}
} 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...");
}
}
return waiters.iterator();
}
Aggregations