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