Mercurial > hg > heapstats
changeset 161:cd0f0916adec
Bug 2923: [REFACTORING][JDK 9] Refactoring deadlock finder
author | Yasumasa Suenaga <yasuenag@gmail.com> |
---|---|
date | Mon, 18 Apr 2016 21:29:04 +0900 |
parents | 6908c38421c4 |
children | 2ff1af5592d4 |
files | agent/src/heapstats-engines/deadlockFinder.cpp agent/src/heapstats-engines/deadlockFinder.hpp agent/src/heapstats-engines/logMain.cpp agent/src/heapstats-engines/vmFunctions.cpp agent/src/heapstats-engines/vmFunctions.hpp agent/src/heapstats-engines/vmVariables.cpp agent/src/heapstats-engines/vmVariables.hpp |
diffstat | 7 files changed, 369 insertions(+), 414 deletions(-) [+] |
line wrap: on
line diff
--- a/agent/src/heapstats-engines/deadlockFinder.cpp Mon Apr 18 21:28:47 2016 +0900 +++ b/agent/src/heapstats-engines/deadlockFinder.cpp Mon Apr 18 21:29:04 2016 +0900 @@ -22,6 +22,7 @@ #include <sys/syscall.h> #include "globals.hpp" +#include "vmFunctions.hpp" #include "vmVariables.hpp" #include "libmain.hpp" #include "deadlockFinder.hpp" @@ -52,53 +53,6 @@ */ #define THREAD_IN_JAVA 8 -/*! - * \brief String of symbol which is function getting monitor's owner. - */ -#define GETLOCKOWNER_SYMBOL "_ZN18ObjectSynchronizer14get_lock_ownerE6Handleb" - -/*! - * \brief String of symbol which is function getting this thread. - */ -#define GETTHISTHREAD_SYMBOL "_ZN18ThreadLocalStorage15get_thread_slowEv" - -/*! - * \brief String of symbol which is function create ThreadSafepointState. - */ -#define THREADSAFEPOINTSTATE_CREATE_SYMBOL \ - "_ZN20ThreadSafepointState6createEP10JavaThread" - -/*! - * \brief String of symbol which is function destroy ThreadSafepointState. - */ -#define THREADSAFEPOINTSTATE_DESTROY_SYMBOL \ - "_ZN20ThreadSafepointState7destroyEP10JavaThread" - -/*! - * \brief String of symbol which is function monitor locking. - */ -#define MONITOR_LOCK_SYMBOL "_ZN7Monitor4lockEv" - -/*! - * \brief String of symbol which is function monitor locking. - */ -#define MONITOR_LOCK_WTIHOUT_CHECK_SYMBOL \ - "_ZN7Monitor28lock_without_safepoint_checkEv" - -/*! - * \brief String of symbol which is function monitor unlocking. - */ -#define MONITOR_UNLOCK_SYMBOL "_ZN7Monitor6unlockEv" - -/*! - * \brief String of symbol which is function monitor owned by self. - */ -#define MONITOR_OWNED_BY_SELF_SYMBOL "_ZNK7Monitor13owned_by_selfEv" - -/*! - * \brief String of symbol which is function "Threads_lock" monitor. - */ -#define THREADS_LOCK_SYMBOL "Threads_lock" /* Class static variables. */ @@ -107,86 +61,6 @@ */ TDeadlockFinder *TDeadlockFinder::inst = NULL; -/*! - * \brief Flag of deadlock is checkable now. - */ -bool TDeadlockFinder::flagCheckableDeadlock = false; - -/*! - * \brief Offset of field "osthread" in class "JavaThread". - */ -off_t TDeadlockFinder::ofsJavaThreadOsthread = -1; - -/*! - * \brief Offset of field "_threadObj" in class "JavaThread". - */ -off_t TDeadlockFinder::ofsJavaThreadThreadObj = -1; - -/*! - * \brief Offset of field "_thread_state" in class "JavaThread". - */ -off_t TDeadlockFinder::ofsJavaThreadThreadState = -1; - -/*! - * \brief Offset of field "_current_pending_monitor" in class "Thread". - */ -off_t TDeadlockFinder::ofsThreadCurrentPendingMonitor = -1; - -/*! - * \brief Offset of field "_thread_id" in class "OSThread". - */ -off_t TDeadlockFinder::ofsOSThreadThreadId = -1; - -/*! - * \brief Offset of field "_object" in class "ObjectMonitor". - */ -off_t TDeadlockFinder::ofsObjectMonitorObject = -1; - -/*! - * \brief Function pointer of "ObjectSynchronizer::get_lock_owner". - */ -TVMGetLockOwnerFunction TDeadlockFinder::get_lock_owner = NULL; - -/*! - * \brief Function pointer of "ThreadLocalStorage::get_thread_slow". - */ -TVMGetThisThreadFunction TDeadlockFinder::get_this_thread = NULL; - -/*! - * \brief Function pointer of "void ThreadSafepointState::create". - */ -TVMThreadFunction TDeadlockFinder::threadSafepointStateCreate = NULL; - -/*! - * \brief Function pointer of "void ThreadSafepointState::destroy". - */ -TVMThreadFunction TDeadlockFinder::threadSafepointStateDestroy = NULL; - -/*! - * \brief Function pointer of "void Monitor::lock()". - */ -TVMMonitorFunction TDeadlockFinder::monitor_lock = NULL; - -/*! - * \brief Function pointer of - * "void Monitor::lock_without_safepoint_check()". - */ -TVMMonitorFunction TDeadlockFinder::monitor_lock_without_check = NULL; - -/*! - * \brief Function pointer of "void Monitor::unlock()". - */ -TVMMonitorFunction TDeadlockFinder::monitor_unlock = NULL; - -/*! - * \brief Function pointer of "bool Monitor::owned_by_self()". - */ -TVMOwnedBySelfFunction TDeadlockFinder::monitor_owned_by_self = NULL; - -/*! - * \brief Variable pointer of "Threads_lock" monitor. - */ -void *TDeadlockFinder::threads_lock = NULL; /* Common methods. */ @@ -292,76 +166,13 @@ /* Variable for return code. */ bool result = true; - /* Get function of ObjectSynchronizer::get_lock_owner(). */ - get_lock_owner = - (TVMGetLockOwnerFunction)symFinder->findSymbol(GETLOCKOWNER_SYMBOL); - - /* Get function of this thread with JVM inner class instance. */ - get_this_thread = - (TVMGetThisThreadFunction)symFinder->findSymbol(GETTHISTHREAD_SYMBOL); - - /* Get function of thread operation. */ - threadSafepointStateCreate = (TVMThreadFunction)symFinder->findSymbol( - THREADSAFEPOINTSTATE_CREATE_SYMBOL); - threadSafepointStateDestroy = (TVMThreadFunction)symFinder->findSymbol( - THREADSAFEPOINTSTATE_DESTROY_SYMBOL); - - /* Get function of monitor operation. */ - monitor_lock = (TVMMonitorFunction)symFinder->findSymbol(MONITOR_LOCK_SYMBOL); - monitor_lock_without_check = (TVMMonitorFunction)symFinder->findSymbol( - MONITOR_LOCK_WTIHOUT_CHECK_SYMBOL); - monitor_unlock = - (TVMMonitorFunction)symFinder->findSymbol(MONITOR_UNLOCK_SYMBOL); - monitor_owned_by_self = (TVMOwnedBySelfFunction)symFinder->findSymbol( - MONITOR_OWNED_BY_SELF_SYMBOL); - - /* Get function of "Threads_lock" monitor. */ - threads_lock = symFinder->findSymbol(THREADS_LOCK_SYMBOL); - - /* if failure get function pointer "get_lock_owner()". */ - if (unlikely(get_lock_owner == NULL || get_this_thread == NULL || - threadSafepointStateCreate == NULL || - threadSafepointStateDestroy == NULL || monitor_lock == NULL || - monitor_lock_without_check == NULL || monitor_unlock == NULL || - monitor_owned_by_self == NULL || threads_lock == NULL)) { - logger->printWarnMsg("Failure search deadlock function's symbol."); + try { + inst = new TDeadlockFinder(event); + } catch (...) { + logger->printCritMsg("Cannot initialize TDeadlockFinder."); result = false; } - /* Symbol offsets. */ - TOffsetNameMap symOffsetList[] = { - {"JavaThread", "_osthread", &ofsJavaThreadOsthread, NULL}, - {"JavaThread", "_threadObj", &ofsJavaThreadThreadObj, NULL}, - {"JavaThread", "_thread_state", &ofsJavaThreadThreadState, NULL}, - {"Thread", "_current_pending_monitor", &ofsThreadCurrentPendingMonitor, - NULL}, - {"OSThread", "_thread_id", &ofsOSThreadThreadId, NULL}, - {"ObjectMonitor", "_object", &ofsObjectMonitorObject, NULL}, - /* End marker. */ - {NULL, NULL, NULL}}; - - /* Search offset. */ - vmScanner->GetDataFromVMStructs(symOffsetList); - - /* If failure get offset information. */ - if (unlikely(ofsJavaThreadOsthread == -1 || ofsJavaThreadThreadObj == -1 || - ofsJavaThreadThreadState == -1 || - ofsThreadCurrentPendingMonitor == -1 || - ofsOSThreadThreadId == -1 || ofsObjectMonitorObject == -1)) { - logger->printWarnMsg("Failure search offset in VMStructs."); - result = false; - } - - if (result) { - try { - inst = new TDeadlockFinder(event); - } catch (...) { - logger->printCritMsg("Cannot initialize TDeadlockFinder."); - result = false; - } - } - - flagCheckableDeadlock = result; return result; } @@ -486,90 +297,91 @@ return 0; } + TVMFunctions *vmFunc = TVMFunctions::getInstance(); + TVMVariables *vmVal = TVMVariables::getInstance(); int deadlockCount = 0; - if (likely(flagCheckableDeadlock)) { - void *thisThreadPtr = get_this_thread(); - void *thread_lock = *(void **)threads_lock; - if (unlikely(thisThreadPtr == NULL || thread_lock == NULL)) { - /* - * Thread class in JVM and thread lock should be set. - * TDeadlockFinder::checkDeadlock() is called by MonitorContendedEnter - * JVMTI event. If this event is fired, current (this) thread must be - * live. - */ - logger->printWarnMsg( + void *thisThreadPtr = vmFunc->GetThread(); + void *thread_lock = *(void **)vmVal->getThreadsLock(); + if (unlikely(thisThreadPtr == NULL || thread_lock == NULL)) { + /* + * Thread class in JVM and thread lock should be set. + * TDeadlockFinder::checkDeadlock() is called by MonitorContendedEnter + * JVMTI event. If this event is fired, current (this) thread must be + * live. + */ + logger->printWarnMsg( "Deadlock detection failed: Cannot get current thread info."); - return 0; - } + return 0; + } + + /* Get self thread id. */ + pid_t threadId = syscall(SYS_gettid); + + int *status = (int *)incAddress(thisThreadPtr, + vmVal->getOfsJavaThreadThreadState()); + int original_status = *status; - /* Get self thread id. */ - pid_t threadId = syscall(SYS_gettid); + /* + * Normally thread status is "_thread_in_native" + * when thread is running in JVMTI event. + * But thread status maybe changed "_thread_in_vm", + * if call "get_lock_owner" and set true to paramter "doLock". + * If VMThread found this thread has such status + * when call "examine_state_of_thread" at synchronizing safepoint, + * By JVM decided that the thread is waiting VM and callback, + * thread state at safepoint set "_call_back" flag. + * Besides, at end of JVMTI envent callback, + * thread was changed thread status to "_thread_in_native_trans" + * from "_thread_in_vm" + * and JVM check thread about running status at safepoint. + * JVM misunderstand deadlock occurred, so JVM abort by self. + * Why JVM misunderstood. + * 1, Safepoint code wait "_thread_in_native_trans" thread. + * 2, "_call_back" flag means wait VM and callback. + * -> VMThread wait the thread and the thread wait VMThread. + * + * So thread status reset here by force. + */ + *status = THREAD_IN_VM; - int *status = (int *)incAddress(thisThreadPtr, ofsJavaThreadThreadState); - int original_status = *status; + /* Check deadlock. */ + bool foundDeadlock = findDeadLock(threadId, monitor); + + if (unlikely(foundDeadlock)) { + /* Get threads. */ + getLockedThreads(threadId, monitor, list); + + /* Count list item. */ + for (TDeadlockList *item = (*list); item != NULL; item = item->next) { + deadlockCount++; + } + } + + if (*status == THREAD_IN_VM) { + bool needLock = !vmFunc->MonitorOwnedBySelf(thread_lock); /* - * Normally thread status is "_thread_in_native" - * when thread is running in JVMTI event. - * But thread status maybe changed "_thread_in_vm", - * if call "get_lock_owner" and set true to paramter "doLock". - * If VMThread found this thread has such status - * when call "examine_state_of_thread" at synchronizing safepoint, - * By JVM decided that the thread is waiting VM and callback, - * thread state at safepoint set "_call_back" flag. - * Besides, at end of JVMTI envent callback, - * thread was changed thread status to "_thread_in_native_trans" - * from "_thread_in_vm" - * and JVM check thread about running status at safepoint. - * JVM misunderstand deadlock occurred, so JVM abort by self. - * Why JVM misunderstood. - * 1, Safepoint code wait "_thread_in_native_trans" thread. - * 2, "_call_back" flag means wait VM and callback. - * -> VMThread wait the thread and the thread wait VMThread. - * - * So thread status reset here by force. + * Lock monitor to avoiding a collision + * with safepoint operation to "ThreadSafepointState". + * E.g. "examine_state_of_thread". */ - *status = THREAD_IN_VM; - - /* Check deadlock. */ - bool foundDeadlock = findDeadLock(threadId, monitor); - - if (unlikely(foundDeadlock)) { - /* Get threads. */ - getLockedThreads(threadId, monitor, list); - - /* Count list item. */ - for (TDeadlockList *item = (*list); item != NULL; item = item->next) { - deadlockCount++; + if (likely(needLock)) { + if (isAtSafepoint()) { + vmFunc->MonitorLockWithoutSafepointCheck(thread_lock); + } else { + vmFunc->MonitorLock(thread_lock); } } - if (*status == THREAD_IN_VM) { - bool needLock = !monitor_owned_by_self(thread_lock); + /* Reset "_thread_state". */ + *status = original_status; + /* Reset "_safepoint_state". */ + vmFunc->ThreadSafepointStateDestroy(thisThreadPtr); + vmFunc->ThreadSafepointStateCreate(thisThreadPtr); - /* - * Lock monitor to avoiding a collision - * with safepoint operation to "ThreadSafepointState". - * E.g. "examine_state_of_thread". - */ - if (likely(needLock)) { - if (isAtSafepoint()) { - monitor_lock_without_check(thread_lock); - } else { - monitor_lock(thread_lock); - } - } - - /* Reset "_thread_state". */ - *status = original_status; - /* Reset "_safepoint_state". */ - threadSafepointStateDestroy(thisThreadPtr); - threadSafepointStateCreate(thisThreadPtr); - - /* Release monitor. */ - if (likely(needLock)) { - monitor_unlock(thread_lock); - } + /* Release monitor. */ + if (likely(needLock)) { + vmFunc->MonitorUnlock(thread_lock); } } @@ -673,6 +485,8 @@ * \param monitor [in] Monitor object of thread contended. */ FASTCALL bool TDeadlockFinder::findDeadLock(pid_t startId, jobject monitor) { + TVMFunctions *vmFunc = TVMFunctions::getInstance(); + TVMVariables *vmVal = TVMVariables::getInstance(); void *threadPtr = NULL; int *status = NULL; void *nativeThread = NULL; @@ -681,7 +495,7 @@ jobject monitorOop = NULL; /* Get owner thread of this monitor. */ - threadPtr = get_lock_owner(monitor, !isAtSafepoint()); + threadPtr = vmFunc->GetLockOwner(monitor, !isAtSafepoint()); /* No deadlock (no owner thread of this monitor). */ if (unlikely(threadPtr == NULL)) { @@ -693,7 +507,8 @@ /* Get OSThread ptr related to JavaThread. */ nativeThread = - (void *)*(ptrdiff_t *)incAddress(threadPtr, ofsJavaThreadOsthread); + (void *)*(ptrdiff_t *)incAddress(threadPtr, + vmVal->getOfsJavaThreadOsthread()); /* If failure get native thread. */ if (unlikely(nativeThread == NULL)) { @@ -701,7 +516,7 @@ } /* Get nid (LWP ID). */ - ownerId = (pid_t *)incAddress(nativeThread, ofsOSThreadThreadId); + ownerId = (pid_t *)incAddress(nativeThread, vmVal->getOfsOSThreadThreadId()); /* If occurred deadlock. */ if (unlikely(*ownerId == startId)) { @@ -710,7 +525,7 @@ } /* Thread status check. */ - status = (int *)incAddress(threadPtr, ofsJavaThreadThreadState); + status = (int *)incAddress(threadPtr, vmVal->getOfsJavaThreadThreadState()); if ((*status == THREAD_IN_JAVA) || (*status == THREAD_IN_VM)) { /* Owner thread is running. */ return false; @@ -718,13 +533,14 @@ /* Get ObjectMonitor pointer. */ contendedMonitor = (void *)*(ptrdiff_t *)incAddress( - threadPtr, ofsThreadCurrentPendingMonitor); + threadPtr, vmVal->getOfsThreadCurrentPendingMonitor()); /* If pointer is illegal. */ if (unlikely(contendedMonitor == NULL)) { return false; } - monitorOop = (jobject)incAddress(contendedMonitor, ofsObjectMonitorObject); + monitorOop = (jobject)incAddress(contendedMonitor, + vmVal->getOfsObjectMonitorObject()); /* If java thread already has monitor. */ if (unlikely((monitorOop == NULL) || (monitorOop == monitor))) { return false; @@ -744,6 +560,8 @@ */ void TDeadlockFinder::getLockedThreads(pid_t startId, jobject monitor, TDeadlockList **list) { + TVMFunctions *vmFunc = TVMFunctions::getInstance(); + TVMVariables *vmVal = TVMVariables::getInstance(); pid_t *ownerId = NULL; TDeadlockList *listHead = NULL; TDeadlockList *oldRec = NULL; @@ -758,7 +576,7 @@ TDeadlockList *threadRec = NULL; /* Get owner thread of this monitor. */ - threadPtr = get_lock_owner(monitor, !isAtSafepoint()); + threadPtr = vmFunc->GetLockOwner(monitor, !isAtSafepoint()); if (unlikely(threadPtr == NULL)) { /* Shouldn't reach to here. */ @@ -769,7 +587,8 @@ } /* Convert to jni object. */ - jThreadObj = (jthread)incAddress(threadPtr, ofsJavaThreadThreadObj); + jThreadObj = (jthread)incAddress(threadPtr, + vmVal->getOfsJavaThreadThreadObj()); /* Create list item. */ threadRec = (TDeadlockList *)malloc(sizeof(TDeadlockList)); @@ -794,7 +613,8 @@ /* Get OSThread ptr related to JavaThread. */ nativeThread = - (void *)*(ptrdiff_t *)incAddress(threadPtr, ofsJavaThreadOsthread); + (void *)*(ptrdiff_t *)incAddress(threadPtr, + vmVal->getOfsJavaThreadOsthread()); if (unlikely(nativeThread == NULL)) { /* Shouldn't reach to here. */ @@ -805,7 +625,8 @@ } /* Get nid (LWP ID). */ - ownerId = (pid_t *)incAddress(nativeThread, ofsOSThreadThreadId); + ownerId = (pid_t *)incAddress(nativeThread, + vmVal->getOfsOSThreadThreadId()); /* If all thread already has collected. */ if (*ownerId == startId) { @@ -814,7 +635,7 @@ /* Get ObjectMonitor pointer. */ contendedMonitor = (void *)*(ptrdiff_t *)incAddress( - threadPtr, ofsThreadCurrentPendingMonitor); + threadPtr, vmVal->getOfsThreadCurrentPendingMonitor()); if (unlikely(contendedMonitor == NULL)) { /* Shouldn't reach to here. */ @@ -824,7 +645,8 @@ break; } - monitor = (jobject)incAddress(contendedMonitor, ofsObjectMonitorObject); + monitor = (jobject)incAddress(contendedMonitor, + vmVal->getOfsObjectMonitorObject()); /* If illegal state. */ if (unlikely(monitor == NULL)) {
--- a/agent/src/heapstats-engines/deadlockFinder.hpp Mon Apr 18 21:28:47 2016 +0900 +++ b/agent/src/heapstats-engines/deadlockFinder.hpp Mon Apr 18 21:29:04 2016 +0900 @@ -48,41 +48,6 @@ typedef void (*TDeadlockEventFunc)(jvmtiEnv *jvmti, JNIEnv *env, TInvokeCause cause); -/*! - * \brief function type of - * "JavaThread* ObjectSynchronizer::get_lock_owner(Handle h_obj, bool doLock)". - * \param monitor_oop [in] Target monitor oop. - * \param doLock [in] Enable oop lock. - * \return Monitor owner thread oop.<br> - * Value is NULL, if owner is none. - */ -typedef void *(*TVMGetLockOwnerFunction)(void *monitor_oop, bool doLock); - -/*! - * \brief function type of - * "Thread* ThreadLocalStorage::get_thread_slow()". - * \return Running this thread. - */ -typedef void *(*TVMGetThisThreadFunction)(void); - -/*! - * \brief function type of common thread operation. - * \param thread [in] Target thread object is inner JVM class instance. - */ -typedef void (*TVMThreadFunction)(void *thread); - -/*! - * \brief function type of common monitor operation. - * \param monitor_oop [in] Target monitor oop. - */ -typedef void (*TVMMonitorFunction)(void *monitor_oop); - -/*! - * \brief function type of common monitor operation. - * \param monitor_oop [in] Target monitor oop. - * \return Thread is owned monitor. - */ -typedef bool (*TVMOwnedBySelfFunction)(void *monitor_oop); /*! * \brief This type is stored deadlock occurred thread list. @@ -179,14 +144,6 @@ const inline jlong getDeadlockTime(void) { return occurTime; }; /*! - * \brief Get function initialized flag. - * \return Flag of deadlock is checkable now. - */ - const static inline bool isCheckableDeadlock(void) { - return flagCheckableDeadlock; - }; - - /*! * \brief Get singleton instance of TDeadlockFinder. * \return Singleton instance of TDeadlockFinder. */ @@ -245,87 +202,6 @@ static void getLockedThreads(pid_t startId, jobject monitor, TDeadlockList **list); - /*! - * \brief Flag of deadlock is checkable now. - */ - static bool flagCheckableDeadlock; - - /*! - * \brief Offset of field "osthread" in class "JavaThread". - */ - static off_t ofsJavaThreadOsthread; - - /*! - * \brief Offset of field "_threadObj" in class "JavaThread". - */ - static off_t ofsJavaThreadThreadObj; - - /*! - * \brief Offset of field "_thread_state" in class "JavaThread". - */ - static off_t ofsJavaThreadThreadState; - - /*! - * \brief Offset of field "_current_pending_monitor" in class "Thread". - */ - static off_t ofsThreadCurrentPendingMonitor; - - /*! - * \brief Offset of field "_thread_id" in class "OSThread". - */ - static off_t ofsOSThreadThreadId; - - /*! - * \brief Offset of field "_object" in class "ObjectMonitor". - */ - static off_t ofsObjectMonitorObject; - - /*! - * \brief Function pointer of "ObjectSynchronizer::get_lock_owner". - */ - static TVMGetLockOwnerFunction get_lock_owner; - - /*! - * \brief Function pointer of "ThreadLocalStorage::get_thread_slow". - */ - static TVMGetThisThreadFunction get_this_thread; - - /*! - * \brief Function pointer of "void ThreadSafepointState::create". - */ - static TVMThreadFunction threadSafepointStateCreate; - - /*! - * \brief Function pointer of "void ThreadSafepointState::destroy". - */ - static TVMThreadFunction threadSafepointStateDestroy; - - /*! - * \brief Function pointer of "void Monitor::lock()". - */ - static TVMMonitorFunction monitor_lock; - - /*! - * \brief Function pointer of - * "void Monitor::lock_without_safepoint_check()". - */ - static TVMMonitorFunction monitor_lock_without_check; - - /*! - * \brief Function pointer of "void Monitor::unlock()". - */ - static TVMMonitorFunction monitor_unlock; - - /*! - * \brief Function pointer of "bool Monitor::owned_by_self()". - */ - static TVMOwnedBySelfFunction monitor_owned_by_self; - - /*! - * \brief Variable pointer of "Threads_lock" monitor. - */ - static void *threads_lock; - private: /*! * \brief Singleton instance of TDeadlockFinder.
--- a/agent/src/heapstats-engines/logMain.cpp Mon Apr 18 21:28:47 2016 +0900 +++ b/agent/src/heapstats-engines/logMain.cpp Mon Apr 18 21:29:04 2016 +0900 @@ -315,18 +315,13 @@ flagLogSignal = 0; flagAllLogSignal = 0; - if (likely(TDeadlockFinder::isCheckableDeadlock())) { - if (conf->TriggerOnLogLock()->get() && !abortionByDeadlock) { - /* Switch deadlock finder state. */ - if (enable) { - TDeadlockFinder::getInstance()->start(jvmti, env); - } else { - TDeadlockFinder::getInstance()->stop(); - } + if (conf->TriggerOnLogLock()->get() && !abortionByDeadlock) { + /* Switch deadlock finder state. */ + if (enable) { + TDeadlockFinder::getInstance()->start(jvmti, env); + } else { + TDeadlockFinder::getInstance()->stop(); } - } else { - /* Disable illegal flag. */ - conf->TriggerOnLogLock()->set(false); } } catch (const char *errMsg) { logger->printWarnMsg(errMsg);
--- a/agent/src/heapstats-engines/vmFunctions.cpp Mon Apr 18 21:28:47 2016 +0900 +++ b/agent/src/heapstats-engines/vmFunctions.cpp Mon Apr 18 21:29:04 2016 +0900 @@ -177,6 +177,63 @@ } } + /* Search "ObjectSynchronizer::get_lock_owner()" function symbol. */ + getLockOwner = (TGetLockOwner) this->symFinder->findSymbol( + GETLOCKOWNER_SYMBOL); + if (unlikely(getLockOwner == NULL)) { + logger->printWarnMsg("ObjectSynchronizer::get_lock_owner() not found."); + return false; + } + + /* Search "ThreadSafepointState::create()" function symbol. */ + threadSafepointStateCreate = (TVMThreadFunction) this->symFinder->findSymbol( + THREADSAFEPOINTSTATE_CREATE_SYMBOL); + if (unlikely(threadSafepointStateCreate == NULL)) { + logger->printWarnMsg("ThreadSafepointState::create() not found."); + return false; + } + + /* Search "ThreadSafepointState::destroy()" function symbol. */ + threadSafepointStateDestroy = (TVMThreadFunction) this->symFinder->findSymbol( + THREADSAFEPOINTSTATE_DESTROY_SYMBOL); + if (unlikely(threadSafepointStateDestroy == NULL)) { + logger->printWarnMsg("ThreadSafepointState::destroy() not found."); + return false; + } + + /* Search "Monitor::lock()" function symbol. */ + monitor_lock = (TVMMonitorFunction) this->symFinder->findSymbol( + MONITOR_LOCK_SYMBOL); + if (unlikely(monitor_lock == NULL)) { + logger->printWarnMsg("Monitor::lock() not found."); + return false; + } + + /* Search "Monitor::lock_without_safepoint_check()" function symbol. */ + monitor_lock_without_safepoint_check = + (TVMMonitorFunction) this->symFinder->findSymbol( + MONITOR_LOCK_WTIHOUT_SAFEPOINT_CHECK_SYMBOL); + if (unlikely(monitor_lock_without_safepoint_check == NULL)) { + logger->printWarnMsg("Monitor::lock_without_safepoint_check() not found."); + return false; + } + + /* Search "Monitor::unlock()" function symbol. */ + monitor_unlock = (TVMMonitorFunction) this->symFinder->findSymbol( + MONITOR_UNLOCK_SYMBOL); + if (unlikely(monitor_unlock == NULL)) { + logger->printWarnMsg("Monitor::unlock() not found."); + return false; + } + + /* Search "Monitor::owned_by_self()" function symbol. */ + monitor_owned_by_self = (TOwnedBySelf) this->symFinder->findSymbol( + MONITOR_OWNED_BY_SELF_SYMBOL); + if (unlikely(monitor_owned_by_self == NULL)) { + logger->printWarnMsg("Monitor::owned_by_self() not found."); + return false; + } + if (vmVal->getUseG1()) { inst->getG1VTableFromSymbol(); }
--- a/agent/src/heapstats-engines/vmFunctions.hpp Mon Apr 18 21:28:47 2016 +0900 +++ b/agent/src/heapstats-engines/vmFunctions.hpp Mon Apr 18 21:29:04 2016 +0900 @@ -113,6 +113,44 @@ #define SR_HANDLER_SYMBOL "_ZL10SR_handleriP7siginfoP8ucontext" #define SR_HANDLER_SYMBOL_FALLBACK "_ZL10SR_handleriP9siginfo_tP8ucontext" +/*! + * \brief Symbol of ObjectSynchronizer::get_lock_owner(). + */ +#define GETLOCKOWNER_SYMBOL "_ZN18ObjectSynchronizer14get_lock_ownerE6Handleb" + +/*! + * \brief Symbol of ThreadSafepointState::create(). + */ +#define THREADSAFEPOINTSTATE_CREATE_SYMBOL \ + "_ZN20ThreadSafepointState6createEP10JavaThread" + +/*! + * \brief Symbol of ThreadSafepointState::destroy(). + */ +#define THREADSAFEPOINTSTATE_DESTROY_SYMBOL \ + "_ZN20ThreadSafepointState7destroyEP10JavaThread" + +/*! + * \brief Symbol of Monitor::lock(). + */ +#define MONITOR_LOCK_SYMBOL "_ZN7Monitor4lockEv" + +/*! + * \brief Symbol of Monitor::lock_without_safepoint_check(). + */ +#define MONITOR_LOCK_WTIHOUT_SAFEPOINT_CHECK_SYMBOL \ + "_ZN7Monitor28lock_without_safepoint_checkEv" + +/*! + * \brief Symbol of Monitor::unlock(). + */ +#define MONITOR_UNLOCK_SYMBOL "_ZN7Monitor6unlockEv" + +/*! + * \brief Symbol of Monitor::owned_by_self(). + */ +#define MONITOR_OWNED_BY_SELF_SYMBOL "_ZNK7Monitor13owned_by_selfEv" + /* Function type definition */ @@ -210,6 +248,35 @@ */ typedef void (*TSR_Handler)(int sig, siginfo_t *siginfo, ucontext_t *context); +/*! + * \brief function type of + * "JavaThread* ObjectSynchronizer::get_lock_owner(Handle h_obj, bool doLock)". + * \param monitor_oop [in] Target monitor oop. + * \param doLock [in] Enable oop lock. + * \return Monitor owner thread oop.<br> + * Value is NULL, if owner is none. + */ +typedef void *(*TGetLockOwner)(void *monitor_oop, bool doLock); + +/*! + * \brief function type of common thread operation. + * \param thread [in] Target thread object is inner JVM class instance. + */ +typedef void (*TVMThreadFunction)(void *thread); + +/*! + * \brief function type of common monitor operation. + * \param monitor_oop [in] Target monitor oop. + */ +typedef void (*TVMMonitorFunction)(void *monitor_oop); + +/*! + * \brief function type of common monitor operation. + * \param monitor_oop [in] Target monitor oop. + * \return Thread is owned monitor. + */ +typedef bool (*TOwnedBySelf)(void *monitor_oop); + /* Exported function in libjvm.so */ extern "C" void *JVM_RegisterSignal(jint sig, void *handler); @@ -269,6 +336,41 @@ */ TSR_Handler sr_handler; + /*! + * \brief Function pointer for "ObjectSynchronizer::get_lock_owner()". + */ + TGetLockOwner getLockOwner; + + /*! + * \brief Function pointer for "ThreadSafepointState::create()". + */ + TVMThreadFunction threadSafepointStateCreate; + + /*! + * \brief Function pointer for "ThreadSafepointState::destroy()". + */ + TVMThreadFunction threadSafepointStateDestroy; + + /*! + * \brief Function pointer for "Monitor::lock()" + */ + TVMMonitorFunction monitor_lock; + + /*! + * \brief Function pointer for "Monitor::lock_without_safepoint_check()". + */ + TVMMonitorFunction monitor_lock_without_safepoint_check; + + /*! + * \brief Function pointer for "Monitor::unlock()". + */ + TVMMonitorFunction monitor_unlock; + + /*! + * \brief Function pointer for "Monitor::owned_by_self()". + */ + TOwnedBySelf monitor_owned_by_self; + /* Class of HeapStats for scanning variables in HotSpot VM */ TSymbolFinder *symFinder; @@ -342,6 +444,37 @@ inline void *GetUserHandlerPointer(void) { return (void *)userHandler; } inline void *GetSRHandlerPointer(void) { return (void *)sr_handler; } + + inline void *GetLockOwner(void *monitor_oop, bool doLock) { + return getLockOwner(monitor_oop, doLock); + } + + inline void ThreadSafepointStateCreate(void *thread) { + threadSafepointStateCreate(thread); + } + + inline void ThreadSafepointStateDestroy(void *thread) { + threadSafepointStateDestroy(thread); + } + + inline void MonitorLock(void *monitor_oop) { + monitor_lock(monitor_oop); + } + + inline void MonitorLockWithoutSafepointCheck(void *monitor_oop) { + monitor_lock_without_safepoint_check(monitor_oop); + } + + inline void MonitorUnlock(void *monitor_oop) { + monitor_unlock(monitor_oop); + } + + /*! + * \brief Function pointer for "Monitor::owned_by_self()". + */ + inline bool MonitorOwnedBySelf(void *monitor_oop) { + return monitor_owned_by_self(monitor_oop); + } }; #endif // VMFUNCTIONS_H
--- a/agent/src/heapstats-engines/vmVariables.cpp Mon Apr 18 21:28:47 2016 +0900 +++ b/agent/src/heapstats-engines/vmVariables.cpp Mon Apr 18 21:29:04 2016 +0900 @@ -75,6 +75,13 @@ BitsPerWordMask = 0; safePointState = NULL; g1StartAddr = NULL; + ofsJavaThreadOsthread = -1; + ofsJavaThreadThreadObj = -1; + ofsJavaThreadThreadState = -1; + ofsThreadCurrentPendingMonitor = -1; + ofsOSThreadThreadId = -1; + ofsObjectMonitorObject = -1; + threads_lock = NULL; #ifdef __LP64__ HeapWordSize = 8; @@ -147,6 +154,13 @@ *(flagList[i].flagPtr) = *tempPtr; } + /* Search "Threads_lock" symbol. */ + threads_lock = symFinder->findSymbol("Threads_lock"); + if (unlikely(threads_lock == NULL)) { + logger->printCritMsg("Threads_lock not found."); + return false; + } + #ifdef __LP64__ if (jvmInfo->isAfterCR6964458()) { bool *tempPtr = NULL; @@ -181,6 +195,13 @@ {"oopDesc", "_metadata._compressed_klass", &ofsCoopKlassAtOop, NULL}, {"oopDesc", "_mark", &ofsMarkAtOop, NULL}, {"Klass", "_name", &ofsNameAtKlass, NULL}, + {"JavaThread", "_osthread", &ofsJavaThreadOsthread, NULL}, + {"JavaThread", "_threadObj", &ofsJavaThreadThreadObj, NULL}, + {"JavaThread", "_thread_state", &ofsJavaThreadThreadState, NULL}, + {"Thread", "_current_pending_monitor", &ofsThreadCurrentPendingMonitor, + NULL}, + {"OSThread", "_thread_id", &ofsOSThreadThreadId, NULL}, + {"ObjectMonitor", "_object", &ofsObjectMonitorObject, NULL}, /* * For CR6990754. @@ -216,6 +237,10 @@ if (unlikely(ofsKlassAtOop == -1 || ofsCoopKlassAtOop == -1 || ofsNameAtKlass == -1 || ofsLengthAtSymbol == -1 || + ofsJavaThreadOsthread == -1 || ofsJavaThreadThreadObj == -1 || + ofsJavaThreadThreadState == -1 || + ofsThreadCurrentPendingMonitor == -1 || + ofsOSThreadThreadId == -1 || ofsObjectMonitorObject == -1 || ofsBodyAtSymbol == -1 || ofsVTableSizeAtInsKlass == -1 || ofsITableSizeAtInsKlass == -1 || (!jvmInfo->isAfterCR7017732() &&
--- a/agent/src/heapstats-engines/vmVariables.hpp Mon Apr 18 21:28:47 2016 +0900 +++ b/agent/src/heapstats-engines/vmVariables.hpp Mon Apr 18 21:29:04 2016 +0900 @@ -36,6 +36,7 @@ */ #define SAFEPOINT_STATE_SYMBOL "_ZN20SafepointSynchronize6_stateE" + /* extern variables */ extern "C" void *collectedHeap; @@ -276,6 +277,41 @@ */ void *g1StartAddr; + /*! + * \brief offset of _osthread field in JavaThread. + */ + off_t ofsJavaThreadOsthread; + + /*! + * \brief offset of _threadObj field in JavaThread. + */ + off_t ofsJavaThreadThreadObj; + + /*! + * \brief offset of _thread_state field in JavaThread. + */ + off_t ofsJavaThreadThreadState; + + /*! + * \brief offset of _current_pending_monitor in Thread. + */ + off_t ofsThreadCurrentPendingMonitor; + + /*! + * \brief offset of _thread_id in OSThread. + */ + off_t ofsOSThreadThreadId; + + /*! + * \brief offset of _object in ObjectMonitor. + */ + off_t ofsObjectMonitorObject; + + /*! + * \brief Pointer of Threads_lock monitor in HotSpot. + */ + void *threads_lock; + /* Class of HeapStats for scanning variables in HotSpot VM */ TSymbolFinder *symFinder; TVMStructScanner *vmScanner; @@ -400,6 +436,17 @@ inline int getBitsPerWordMask() { return BitsPerWordMask; }; inline int getSafePointState() { return *safePointState; }; inline void *getG1StartAddr() { return g1StartAddr; }; + inline off_t getOfsJavaThreadOsthread() { return ofsJavaThreadOsthread; }; + inline off_t getOfsJavaThreadThreadObj() { return ofsJavaThreadThreadObj; }; + inline off_t getOfsJavaThreadThreadState() { + return ofsJavaThreadThreadState; + }; + inline off_t getOfsThreadCurrentPendingMonitor() { + return ofsThreadCurrentPendingMonitor; + }; + inline off_t getOfsOSThreadThreadId() { return ofsOSThreadThreadId; }; + inline off_t getOfsObjectMonitorObject() { return ofsObjectMonitorObject; }; + inline void *getThreadsLock() { return threads_lock; }; }; #endif // VMVARIABLES_H