use of com.ibm.j9ddr.vm29.pointer.generated.J9VMThreadPointer in project openj9 by eclipse.
the class MonitorsCommand method j9vmthreadCommand.
/**
* See {@link MonitorsCommand#helpCommand(String[], PrintStream)} for
* function documentation
*
* @param args
* command args
* @param out
* the output stream
* @throws DDRInteractiveCommandException
*/
private void j9vmthreadCommand(String[] args, PrintStream out) throws DDRInteractiveCommandException {
if (args.length < 2) {
out.println("This command takes one address argument: \"!monitors j9vmthread <address>\"");
return;
}
try {
long address = CommandUtils.parsePointer(args[1], J9BuildFlags.env_data64);
VoidPointer ptr = VoidPointer.cast(address);
J9JavaVMPointer vm = J9RASHelper.getVM(DataType.getJ9RASPointer());
J9VMThreadPointer thread = null;
GCVMThreadListIterator threadIterator = GCVMThreadListIterator.from();
while (threadIterator.hasNext()) {
if (ptr.equals(threadIterator.next())) {
thread = J9VMThreadPointer.cast(ptr);
}
}
if (null == thread) {
throw new DDRInteractiveCommandException(String.format("Could not find any j9vmthread at address %s\n", ptr.getHexAddress()));
}
// Step 1: Print the general info for the VM and native threads:
out.println(String.format("!j9vmthread 0x%08x\t!j9thread 0x%08x\t// %s", thread.getAddress(), thread.osThread().getAddress(), J9VMThreadHelper.getName(thread)));
printMonitorsForJ9VMThread(out, vm, thread);
printMonitorsForJ9Thread(out, vm, thread.osThread());
} catch (CorruptDataException e) {
throw new DDRInteractiveCommandException(e);
}
}
use of com.ibm.j9ddr.vm29.pointer.generated.J9VMThreadPointer in project openj9 by eclipse.
the class StackWalkCommand method run.
public void run(String command, String[] args, Context context, PrintStream out) throws DDRInteractiveCommandException {
try {
UDATAPointer sp = UDATAPointer.NULL;
UDATAPointer arg0EA = UDATAPointer.NULL;
U8Pointer pc = U8Pointer.NULL;
J9MethodPointer literals = J9MethodPointer.NULL;
J9VMEntryLocalStoragePointer entryLocalStorage = J9VMEntryLocalStoragePointer.NULL;
String[] realArgs = null;
if (args.length != 0) {
realArgs = args[0].split(",");
}
if (args.length == 0 || !((realArgs.length == 1) || (realArgs.length == 5) || (realArgs.length == 6))) {
CommandUtils.dbgPrint(out, "Usage:\n");
CommandUtils.dbgPrint(out, "\t!stack thread\n");
CommandUtils.dbgPrint(out, "\t!stack thread,sp,a0,pc,literals\n");
CommandUtils.dbgPrint(out, "\t!stack thread,sp,a0,pc,literals,els\n");
CommandUtils.dbgPrint(out, "\tUse !stackslots instead of !stack to see slot values\n");
if (J9BuildFlags.interp_nativeSupport) {
CommandUtils.dbgPrint(out, "\tUse !jitstack or !jitstackslots to start the walk at a JIT frame\n");
}
// dbgPrintRegisters(1);
return;
}
long address = CommandUtils.parsePointer(realArgs[0], J9BuildFlags.env_data64);
if (0 == address) {
/* Parse error is captured in CommandUtils.parsePointer method and message is printed */
return;
}
J9VMThreadPointer thread = J9VMThreadPointer.cast(address);
StackWalkerUtils.enableVerboseLogging(3, out);
WalkState walkState = new WalkState();
walkState.flags = J9_STACKWALK_RECORD_BYTECODE_PC_OFFSET;
if (realArgs.length >= 5) {
address = CommandUtils.parsePointer(realArgs[1], J9BuildFlags.env_data64);
sp = UDATAPointer.cast(address);
address = CommandUtils.parsePointer(realArgs[2], J9BuildFlags.env_data64);
arg0EA = UDATAPointer.cast(address);
address = CommandUtils.parsePointer(realArgs[3], J9BuildFlags.env_data64);
pc = U8Pointer.cast(address);
address = CommandUtils.parsePointer(realArgs[4], J9BuildFlags.env_data64);
literals = J9MethodPointer.cast(address);
} else {
sp = thread.sp();
arg0EA = thread.arg0EA();
pc = thread.pc();
literals = thread.literals();
}
if (realArgs.length >= 6) {
address = CommandUtils.parsePointer(realArgs[5], J9BuildFlags.env_data64);
entryLocalStorage = J9VMEntryLocalStoragePointer.cast(address);
} else {
if (J9BuildFlags.interp_nativeSupport) {
entryLocalStorage = thread.entryLocalStorage();
}
}
if (command.equalsIgnoreCase("!stackslots")) {
walkState.flags |= J9_STACKWALK_ITERATE_O_SLOTS;
// 100 is highly arbitrary but basically means "print everything".
// It is used in jextract where the message levels have been copied
// from to begin with, so it should mean we get the same output.
StackWalkerUtils.enableVerboseLogging(100, out);
walkState.callBacks = new BaseStackWalkerCallbacks();
} else {
StackWalkerUtils.enableVerboseLogging(0, out);
walkState.callBacks = new TerseStackWalkerCallbacks();
walkState.flags |= J9_STACKWALK_ITERATE_FRAMES;
}
walkState.walkThread = thread;
StackWalkResult result = StackWalker.walkStackFrames(walkState, sp, arg0EA, pc, literals, entryLocalStorage);
if (result != StackWalkResult.NONE) {
out.println("Stack walk result: " + result);
}
StackWalkerUtils.disableVerboseLogging();
out.flush();
} catch (CorruptDataException e) {
throw new DDRInteractiveCommandException(e);
}
}
use of com.ibm.j9ddr.vm29.pointer.generated.J9VMThreadPointer in project openj9 by eclipse.
the class SetVMCommand method run.
/**
* Runs the !setvm command.
* 1. Checks whether correct number of args passed which is 1.
* 2. If condition 1 is successful, checks whether the passed arg is a valid integer, decimal or hexadecimal.
* 3. If condition 2 is successful, checks whether the address (only arg) is a valid J9JavaVM address.
* 4. If condition 3 is unsuccessful, checks whether the address is a valid J9VMThread address.
*
* If any of the condition 3 or 4 succeeds, then cachedVM is set to new address.
* Otherwise, it prints error msg.
*
* @param command DDR extension command which is setVM for this extension.
* @param args arguments passed with the command
* @param context current context that DDR is running on.
* @param out PrintStream to print the user messages.
* @return void
*/
public void run(String command, String[] args, Context context, PrintStream out) throws DDRInteractiveCommandException {
if (1 != args.length) {
printHelp(out);
return;
}
long address = CommandUtils.parsePointer(args[0], J9BuildFlags.env_data64);
J9JavaVMPointer vmPtr = J9JavaVMPointer.cast(address);
if (testJavaVMPtr(vmPtr)) {
J9RASHelper.setCachedVM(vmPtr);
out.println("VM set to " + vmPtr.getHexAddress());
return;
} else {
/* hmm. It's not a J9JavaVM. Maybe it's a vmThread? */
/* try to read the VM slot */
J9VMThreadPointer threadPtr = J9VMThreadPointer.cast(address);
try {
vmPtr = threadPtr.javaVM();
if (testJavaVMPtr(vmPtr)) {
J9RASHelper.setCachedVM(vmPtr);
out.println("VM set to " + vmPtr.getHexAddress());
return;
}
} catch (CorruptDataException e) {
/* Do Nothing */
}
}
out.println("Error: Specified value (=" + address + ") is not a javaVM or vmThread pointer, VM not set");
}
use of com.ibm.j9ddr.vm29.pointer.generated.J9VMThreadPointer in project openj9 by eclipse.
the class VmCheckCommand method checkJ9VMThreadSanity.
/*
* Based on vmchk/checkthreads.c r1.5
*
* J9VMThread sanity:
* Valid VM check:
* J9VMThread->javaVM->javaVM == J9VMThread->javaVM.
*
* Exclusive access check:
* If any J9VMThread has exclusive access, ensure no other thread has exclusive or vm access.
*/
private void checkJ9VMThreadSanity(J9JavaVMPointer javaVM, PrintStream out) throws CorruptDataException {
GCVMThreadListIterator gcvmThreadListIterator = GCVMThreadListIterator.from();
int count = 0;
int numberOfThreadsWithVMAccess = 0;
boolean exclusiveVMAccess = javaVM.exclusiveAccessState().eq(J9_XACCESS_EXCLUSIVE);
reportMessage(out, "Checking threads");
while (gcvmThreadListIterator.hasNext()) {
J9VMThreadPointer thread = gcvmThreadListIterator.next();
verifyJ9VMThread(out, thread, javaVM);
if (thread.publicFlags().allBitsIn(J9Consts.J9_PUBLIC_FLAGS_VM_ACCESS)) {
numberOfThreadsWithVMAccess++;
}
count++;
}
if (exclusiveVMAccess && numberOfThreadsWithVMAccess > 1) {
reportError(out, "numberOfThreadsWithVMAccess (%d) > 1 with vm->exclusiveAccessState == J9_XACCESS_EXCLUSIVE", numberOfThreadsWithVMAccess);
}
reportMessage(out, "Checking %d threads done", count);
}
use of com.ibm.j9ddr.vm29.pointer.generated.J9VMThreadPointer in project openj9 by eclipse.
the class DeadlockUtils method findThreadCycle.
/**
* @param vmThread
* @param map
* @throws CorruptDataException
*/
public static void findThreadCycle(J9ThreadPointer aThread, HashMap<Integer, NativeDeadlockGraphNode> deadlocks, HashMap<J9ObjectPointer, Object> objectMonitorsMap) throws CorruptDataException {
// Based on JavaCoreDumpWriter::findThreadCycle()
// Can't stack allocate or (safely) re-purpose an object in Java,
// so we create a new one on each iteration, this is slightly
// different from what is done in javadump.cpp
NativeDeadlockGraphNode node = null;
NativeDeadlockGraphNode prev = null;
do {
// Is there an associated J9VMThread?
J9VMThreadPointer vmThread = J9ThreadHelper.getVMThread(aThread);
boolean isJavaThread = (null != vmThread) && vmThread.notNull();
// Enter waiter (blocked) or notify waiter.
boolean isJavaWaiter = false;
if (isJavaThread) {
// There is, so grab all the J9VMThread related information.
JavaDeadlockGraphNode javaNode = new JavaDeadlockGraphNode();
javaNode.javaThread = vmThread;
J9VMThreadPointer owner = null;
J9ObjectPointer lockObject = null;
J9ThreadAbstractMonitorPointer lock = null;
// Functionally equivalent to getVMThreadStateHelper(...) in thrinfo.c
lockObject = vmThread.blockingEnterObject();
if ((null != lockObject) && lockObject.notNull()) {
// This condition hitting means we are in one of the desired states:
// J9VMTHREAD_STATE_BLOCKED
// J9VMTHREAD_STATE_WAITING, J9VMTHREAD_STATE_WAITING_TIMED
// J9VMTHREAD_STATE_PARKED, J9VMTHREAD_STATE_PARKED_TIMED
isJavaWaiter = true;
// The original native relies on getVMThreadStateHelper(...)
// from thrinfo.c to obtain this information, which is analogous
// to J9VMThreadPointerUtil.getJ9State(...), but we don't actually
// need all that information.
Object current = objectMonitorsMap.get(lockObject);
if (current instanceof ObjectMonitor) {
ObjectMonitor mon = (ObjectMonitor) current;
owner = mon.getOwner();
lock = mon.getInflatedMonitor();
} else if (current instanceof J9ThreadMonitorPointer) {
// System Monitor
J9ThreadMonitorPointer mon = (J9ThreadMonitorPointer) current;
J9ThreadPointer sysThread = mon.owner();
lock = J9ThreadAbstractMonitorPointer.cast(mon);
if (sysThread.notNull()) {
owner = J9ThreadHelper.getVMThread(sysThread);
}
}
if ((null == owner) || owner.isNull() || (owner.equals(vmThread))) {
// See JAZZ103 63676: There are cases where even if we know there is no
// Java deadlock, we should still check for a system deadlock.
// We simply deal with this node as a native one from this point on.
isJavaWaiter = false;
} else {
// N.B. In the native there are comparisons with J9VMTHREAD_STATE_*
// constants as returned by the helper, but here we don't actually need them.
javaNode.javaLock = lock;
javaNode.lockObject = lockObject;
javaNode.cycle = 0;
/* Record current thread and update last node */
javaNode.nativeThread = vmThread.osThread();
deadlocks.put(javaNode.hashCode(), javaNode);
if (null != prev) {
prev.next = javaNode;
}
/* Move around the graph */
prev = javaNode;
/* Peek ahead to see if we're in a possible cycle */
prev.next = deadlocks.get(owner.osThread().hashCode());
aThread = owner.osThread();
}
}
// Have to keep going for the case of Java thread blocking on system monitor.
// We have to write the J9Thread info as well.
node = javaNode;
}
if (false == isJavaThread) {
node = new NativeDeadlockGraphNode();
}
// Now get all of the J9Thread fields (even when we are working with a Java thread).
node.nativeThread = aThread;
J9ThreadMonitorPointer nativeLock = aThread.monitor();
J9ThreadPointer owner = null;
if ((null == nativeLock) || nativeLock.isNull()) {
if (false == isJavaThread) {
return;
}
} else {
node.nativeLock = nativeLock;
owner = nativeLock.owner();
}
// to change the pointers, otherwise we have to set them up.
if (false == isJavaWaiter) {
deadlocks.put(node.hashCode(), node);
if (null != prev) {
prev.next = node;
}
if ((null == owner) || owner.isNull() || (owner.equals(aThread))) {
return;
} else {
/* Move around the graph */
prev = node;
/* Peek ahead to see if we're in a possible cycle */
prev.next = deadlocks.get(owner.hashCode());
aThread = owner;
}
}
} while (// Quit as soon as possible (first node we've already visited).
null == prev.next);
// The rest of the cycles will be found by multiple calls to findThreadCycle(...)
}
Aggregations