Show useful thread information in IllegalMonitorStateExceptions.
Previously we were just throwing the Thread* address.
Change-Id: I511a1e0d4348832d1d6d5b802d579448617fb389
diff --git a/src/monitor.cc b/src/monitor.cc
index 8d6bd19..3efdab6 100644
--- a/src/monitor.cc
+++ b/src/monitor.cc
@@ -239,51 +239,59 @@
va_end(args);
}
+static std::string ThreadToString(Thread* thread) {
+ if (thread == NULL) {
+ return "NULL";
+ }
+ std::ostringstream oss;
+ // TODO: alternatively, we could just return the thread's name.
+ oss << *thread;
+ return oss.str();
+}
+
void Monitor::FailedUnlock(Object* obj, Thread* expected_owner, Thread* found_owner,
Monitor* mon) {
// Acquire thread list lock so threads won't disappear from under us
ScopedThreadListLock tll;
// Re-read owner now that we hold lock
Thread* current_owner = mon != NULL ? mon->owner_ : NULL;
- std::ostringstream expected_ss;
- expected_ss << expected_owner;
if (current_owner == NULL) {
if (found_owner == NULL) {
ThrowIllegalMonitorStateExceptionF("unlock of unowned monitor on object of type '%s'"
" on thread '%s'",
- PrettyTypeOf(obj).c_str(), expected_ss.str().c_str());
+ PrettyTypeOf(obj).c_str(),
+ ThreadToString(expected_owner).c_str());
} else {
// Race: the original read found an owner but now there is none
- std::ostringstream found_ss;
- found_ss << found_owner;
ThrowIllegalMonitorStateExceptionF("unlock of monitor owned by '%s' on object of type '%s'"
" (where now the monitor appears unowned) on thread '%s'",
- found_ss.str().c_str(), PrettyTypeOf(obj).c_str(),
- expected_ss.str().c_str());
+ ThreadToString(found_owner).c_str(),
+ PrettyTypeOf(obj).c_str(),
+ ThreadToString(expected_owner).c_str());
}
} else {
- std::ostringstream current_ss;
- current_ss << current_owner;
if (found_owner == NULL) {
// Race: originally there was no owner, there is now
ThrowIllegalMonitorStateExceptionF("unlock of monitor owned by '%s' on object of type '%s'"
" (originally believed to be unowned) on thread '%s'",
- current_ss.str().c_str(), PrettyTypeOf(obj).c_str(),
- expected_ss.str().c_str());
+ ThreadToString(current_owner).c_str(),
+ PrettyTypeOf(obj).c_str(),
+ ThreadToString(expected_owner).c_str());
} else {
if (found_owner != current_owner) {
// Race: originally found and current owner have changed
- std::ostringstream found_ss;
- found_ss << found_owner;
ThrowIllegalMonitorStateExceptionF("unlock of monitor originally owned by '%s' (now"
" owned by '%s') on object of type '%s' on thread '%s'",
- found_ss.str().c_str(), current_ss.str().c_str(),
- PrettyTypeOf(obj).c_str(), expected_ss.str().c_str());
+ ThreadToString(found_owner).c_str(),
+ ThreadToString(current_owner).c_str(),
+ PrettyTypeOf(obj).c_str(),
+ ThreadToString(expected_owner).c_str());
} else {
ThrowIllegalMonitorStateExceptionF("unlock of monitor owned by '%s' on object of type '%s'"
" on thread '%s",
- current_ss.str().c_str(), PrettyTypeOf(obj).c_str(),
- expected_ss.str().c_str());
+ ThreadToString(current_owner).c_str(),
+ PrettyTypeOf(obj).c_str(),
+ ThreadToString(expected_owner).c_str());
}
}
}