提交 8ca53883 编写于 作者: D dcubed

8007476: assert(the_owner != NULL) failed: Did not find owning Java thread for lock word address

Summary: Make deadlock detection a little more robust in the case of being unable to find the JavaThread associated with an object lock.
Reviewed-by: sla, acorn
上级 4fbeb8df
...@@ -997,13 +997,19 @@ JvmtiEnvBase::get_object_monitor_usage(JavaThread* calling_thread, jobject objec ...@@ -997,13 +997,19 @@ JvmtiEnvBase::get_object_monitor_usage(JavaThread* calling_thread, jobject objec
// move our object at this point. However, our owner value is safe // move our object at this point. However, our owner value is safe
// since it is either the Lock word on a stack or a JavaThread *. // since it is either the Lock word on a stack or a JavaThread *.
owning_thread = Threads::owning_thread_from_monitor_owner(owner, !at_safepoint); owning_thread = Threads::owning_thread_from_monitor_owner(owner, !at_safepoint);
assert(owning_thread != NULL, "sanity check"); // Cannot assume (owning_thread != NULL) here because this function
if (owning_thread != NULL) { // robustness // may not have been called at a safepoint and the owning_thread
// might not be suspended.
if (owning_thread != NULL) {
// The monitor's owner either has to be the current thread, at safepoint // The monitor's owner either has to be the current thread, at safepoint
// or it has to be suspended. Any of these conditions will prevent both // or it has to be suspended. Any of these conditions will prevent both
// contending and waiting threads from modifying the state of // contending and waiting threads from modifying the state of
// the monitor. // the monitor.
if (!at_safepoint && !JvmtiEnv::is_thread_fully_suspended(owning_thread, true, &debug_bits)) { if (!at_safepoint && !JvmtiEnv::is_thread_fully_suspended(owning_thread, true, &debug_bits)) {
// Don't worry! This return of JVMTI_ERROR_THREAD_NOT_SUSPENDED
// will not make it back to the JVM/TI agent. The error code will
// get intercepted in JvmtiEnv::GetObjectMonitorUsage() which
// will retry the call via a VM_GetObjectMonitorUsage VM op.
return JVMTI_ERROR_THREAD_NOT_SUSPENDED; return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
} }
HandleMark hm; HandleMark hm;
......
...@@ -813,6 +813,7 @@ JavaThread* ObjectSynchronizer::get_lock_owner(Handle h_obj, bool doLock) { ...@@ -813,6 +813,7 @@ JavaThread* ObjectSynchronizer::get_lock_owner(Handle h_obj, bool doLock) {
} }
if (owner != NULL) { if (owner != NULL) {
// owning_thread_from_monitor_owner() may also return NULL here
return Threads::owning_thread_from_monitor_owner(owner, doLock); return Threads::owning_thread_from_monitor_owner(owner, doLock);
} }
......
...@@ -4285,7 +4285,9 @@ JavaThread *Threads::owning_thread_from_monitor_owner(address owner, bool doLock ...@@ -4285,7 +4285,9 @@ JavaThread *Threads::owning_thread_from_monitor_owner(address owner, bool doLock
if (owner == (address)p) return p; if (owner == (address)p) return p;
} }
} }
assert(UseHeavyMonitors == false, "Did not find owning Java thread with UseHeavyMonitors enabled"); // Cannot assert on lack of success here since this function may be
// used by code that is trying to report useful problem information
// like deadlock detection.
if (UseHeavyMonitors) return NULL; if (UseHeavyMonitors) return NULL;
// //
...@@ -4303,7 +4305,7 @@ JavaThread *Threads::owning_thread_from_monitor_owner(address owner, bool doLock ...@@ -4303,7 +4305,7 @@ JavaThread *Threads::owning_thread_from_monitor_owner(address owner, bool doLock
} }
} }
} }
assert(the_owner != NULL, "Did not find owning Java thread for lock word address"); // cannot assert on lack of success here; see above comment
return the_owner; return the_owner;
} }
......
/* /*
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -327,8 +327,28 @@ DeadlockCycle* ThreadService::find_deadlocks_at_safepoint(bool concurrent_locks) ...@@ -327,8 +327,28 @@ DeadlockCycle* ThreadService::find_deadlocks_at_safepoint(bool concurrent_locks)
while (waitingToLockMonitor != NULL || waitingToLockBlocker != NULL) { while (waitingToLockMonitor != NULL || waitingToLockBlocker != NULL) {
cycle->add_thread(currentThread); cycle->add_thread(currentThread);
if (waitingToLockMonitor != NULL) { if (waitingToLockMonitor != NULL) {
currentThread = Threads::owning_thread_from_monitor_owner((address)waitingToLockMonitor->owner(), currentThread = Threads::owning_thread_from_monitor_owner(
(address)waitingToLockMonitor->owner(),
false /* no locking needed */); false /* no locking needed */);
if (currentThread == NULL) {
// This function is called at a safepoint so the JavaThread
// that owns waitingToLockMonitor should be findable, but
// if it is not findable, then the previous currentThread is
// blocked permanently. We record this as a deadlock.
num_deadlocks++;
cycle->set_deadlock(true);
// add this cycle to the deadlocks list
if (deadlocks == NULL) {
deadlocks = cycle;
} else {
last->set_next(cycle);
}
last = cycle;
cycle = new DeadlockCycle();
break;
}
} else { } else {
if (concurrent_locks) { if (concurrent_locks) {
if (waitingToLockBlocker->is_a(SystemDictionary::abstract_ownable_synchronizer_klass())) { if (waitingToLockBlocker->is_a(SystemDictionary::abstract_ownable_synchronizer_klass())) {
...@@ -841,7 +861,17 @@ void DeadlockCycle::print_on(outputStream* st) const { ...@@ -841,7 +861,17 @@ void DeadlockCycle::print_on(outputStream* st) const {
owner_desc = " (JVMTI raw monitor),\n which is held by"; owner_desc = " (JVMTI raw monitor),\n which is held by";
} }
currentThread = Threads::owning_thread_from_monitor_owner( currentThread = Threads::owning_thread_from_monitor_owner(
(address)waitingToLockMonitor->owner(), false /* no locking needed */); (address)waitingToLockMonitor->owner(),
false /* no locking needed */);
if (currentThread == NULL) {
// The deadlock was detected at a safepoint so the JavaThread
// that owns waitingToLockMonitor should be findable, but
// if it is not findable, then the previous currentThread is
// blocked permanently.
st->print("%s UNKNOWN_owner_addr=" PTR_FORMAT, owner_desc,
(address)waitingToLockMonitor->owner());
continue;
}
} else { } else {
st->print(" waiting for ownable synchronizer " INTPTR_FORMAT ", (a %s)", st->print(" waiting for ownable synchronizer " INTPTR_FORMAT ", (a %s)",
(address)waitingToLockBlocker, (address)waitingToLockBlocker,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册