Exemple #1
0
jvmtiError
JvmtiEnvBase::get_current_contended_monitor(JavaThread *calling_thread, JavaThread *java_thread, jobject *monitor_ptr) {
#ifdef ASSERT
  uint32_t debug_bits = 0;
#endif
  assert((SafepointSynchronize::is_at_safepoint() ||
          is_thread_fully_suspended(java_thread, false, &debug_bits)),
         "at safepoint or target thread is suspended");
  oop obj = NULL;
  ObjectMonitor *mon = java_thread->current_waiting_monitor();
  if (mon == NULL) {
    // thread is not doing an Object.wait() call
    mon = java_thread->current_pending_monitor();
    if (mon != NULL) {
      // The thread is trying to enter() or raw_enter() an ObjectMonitor.
      obj = (oop)mon->object();
      // If obj == NULL, then ObjectMonitor is raw which doesn't count
      // as contended for this API
    }
    // implied else: no contended ObjectMonitor
  } else {
    // thread is doing an Object.wait() call
    obj = (oop)mon->object();
    assert(obj != NULL, "Object.wait() should have an object");
  }

  if (obj == NULL) {
    *monitor_ptr = NULL;
  } else {
    HandleMark hm;
    Handle     hobj(obj);
    *monitor_ptr = jni_reference(calling_thread, hobj);
  }
  return JVMTI_ERROR_NONE;
}
void DeadlockCycle::print_on(outputStream* st) const {
  st->cr();
  st->print_cr("Found one Java-level deadlock:");
  st->print("=============================");

  JavaThread* currentThread;
  ObjectMonitor* waitingToLockMonitor;
  oop waitingToLockBlocker;
  int len = _threads->length();
  for (int i = 0; i < len; i++) {
    currentThread = _threads->at(i);
    waitingToLockMonitor = (ObjectMonitor*)currentThread->current_pending_monitor();
    waitingToLockBlocker = currentThread->current_park_blocker();
    st->cr();
    st->print_cr("\"%s\":", currentThread->get_thread_name());
    const char* owner_desc = ",\n  which is held by";
    if (waitingToLockMonitor != NULL) {
      st->print("  waiting to lock monitor " INTPTR_FORMAT, waitingToLockMonitor);
      oop obj = (oop)waitingToLockMonitor->object();
      if (obj != NULL) {
        st->print(" (object "INTPTR_FORMAT ", a %s)", (address)obj,
                   (instanceKlass::cast(obj->klass()))->external_name());

        if (!currentThread->current_pending_monitor_is_from_java()) {
          owner_desc = "\n  in JNI, which is held by";
        }
      } else {
        // No Java object associated - a JVMTI raw monitor
        owner_desc = " (JVMTI raw monitor),\n  which is held by";
      }
      currentThread = Threads::owning_thread_from_monitor_owner(
        (address)waitingToLockMonitor->owner(), false /* no locking needed */);
    } else {
      st->print("  waiting for ownable synchronizer " INTPTR_FORMAT ", (a %s)",
                (address)waitingToLockBlocker,
                (instanceKlass::cast(waitingToLockBlocker->klass()))->external_name());
      assert(waitingToLockBlocker->is_a(SystemDictionary::abstract_ownable_synchronizer_klass()),
             "Must be an AbstractOwnableSynchronizer");
      oop ownerObj = java_util_concurrent_locks_AbstractOwnableSynchronizer::get_owner_threadObj(waitingToLockBlocker);
      currentThread = java_lang_Thread::thread(ownerObj);
    }
    st->print("%s \"%s\"", owner_desc, currentThread->get_thread_name());
  }

  st->cr();
  st->cr();

  // Print stack traces
  bool oldJavaMonitorsInStackTrace = JavaMonitorsInStackTrace;
  JavaMonitorsInStackTrace = true;
  st->print_cr("Java stack information for the threads listed above:");
  st->print_cr("===================================================");
  for (int j = 0; j < len; j++) {
    currentThread = _threads->at(j);
    st->print_cr("\"%s\":", currentThread->get_thread_name());
    currentThread->print_stack_on(st);
  }
  JavaMonitorsInStackTrace = oldJavaMonitorsInStackTrace;
}
Exemple #3
0
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC

void markOopDesc::print_on(outputStream* st) const {
  if (is_marked()) {
    st->print(" marked(" INTPTR_FORMAT ")", value());
  } else if (has_monitor()) {
    // have to check has_monitor() before is_locked()
    st->print(" monitor(" INTPTR_FORMAT ")=", value());
    ObjectMonitor* mon = monitor();
    if (mon == NULL) {
      st->print("NULL (this should never be seen!)");
    } else {
      st->print("{count=" INTPTR_FORMAT ",waiters=" INTPTR_FORMAT
                ",recursions=" INTPTR_FORMAT ",owner=" INTPTR_FORMAT "}",
                mon->count(), mon->waiters(), mon->recursions(),
                p2i(mon->owner()));
    }
  } else if (is_locked()) {
    st->print(" locked(" INTPTR_FORMAT ")->", value());
    if (is_neutral()) {
      st->print("is_neutral");
      if (has_no_hash()) {
        st->print(" no_hash");
      } else {
        st->print(" hash=" INTPTR_FORMAT, hash());
      }
      st->print(" age=%d", age());
    } else if (has_bias_pattern()) {
      st->print("is_biased");
      JavaThread* jt = biased_locker();
      st->print(" biased_locker=" INTPTR_FORMAT, p2i(jt));
    } else {
      st->print("??");
    }
  } else {
    assert(is_unlocked() || has_bias_pattern(), "just checking");
    st->print("mark(");
    if (has_bias_pattern()) st->print("biased,");
    st->print("hash %#lx,", hash());
    st->print("age %d)", age());
  }
}
//
// Fabricate heavyweight monitor information for each lightweight monitor
// found in the Java VFrame.
//
void javaVFrame::jvmpi_fab_heavy_monitors(bool query, int* fab_index, int frame_count, GrowableArray<ObjectMonitor*>* fab_list) {
  assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
  ResourceMark rm;

  GrowableArray<MonitorInfo*>* mons = monitors();
  if (mons->is_empty()) return;

  bool found_first_monitor = false;
  for (int index = (mons->length()-1); index >= 0; index--) {
    MonitorInfo* monitor = mons->at(index);
    if (monitor->owner() == NULL) continue; // skip unowned monitor
    //
    // If we haven't found a monitor before, this is the first frame, and
    // the thread is blocked, then we are trying to enter this monitor.
    // We skip it because we have already seen it before from the monitor 
    // cache walk.
    //
    if (!found_first_monitor && frame_count == 0) {
      switch (thread()->thread_state()) {
      case _thread_blocked:
      case _thread_blocked_trans:
        continue;
      }
    }
    found_first_monitor = true;

    markOop mark = monitor->owner()->mark();
    if (mark->has_locker()) {
      if (!query) {   // not just counting so create and store at the current element
        // fabricate the heavyweight monitor from lightweight info
        ObjectMonitor *heavy = new ObjectMonitor();
        heavy->set_object(monitor->owner());  // use the owning object
        heavy->set_owner(thread());           // use thread instead of stack address for speed
        fab_list->at_put(*fab_index, heavy);
      }
      (*fab_index)++;
    }
  }
}
Exemple #5
0
jvmtiError
JvmtiEnvBase::get_object_monitor_usage(JavaThread* calling_thread, jobject object, jvmtiMonitorUsage* info_ptr) {
  HandleMark hm;
  Handle hobj;

  bool at_safepoint = SafepointSynchronize::is_at_safepoint();

  // Check arguments
  {
    oop mirror = JNIHandles::resolve_external_guard(object);
    NULL_CHECK(mirror, JVMTI_ERROR_INVALID_OBJECT);
    NULL_CHECK(info_ptr, JVMTI_ERROR_NULL_POINTER);

    hobj = Handle(mirror);
  }

  JavaThread *owning_thread = NULL;
  ObjectMonitor *mon = NULL;
  jvmtiMonitorUsage ret = {
      NULL, 0, 0, NULL, 0, NULL
  };

  uint32_t debug_bits = 0;
  // first derive the object's owner and entry_count (if any)
  {
    // Revoke any biases before querying the mark word
    if (SafepointSynchronize::is_at_safepoint()) {
      BiasedLocking::revoke_at_safepoint(hobj);
    } else {
      BiasedLocking::revoke_and_rebias(hobj, false, calling_thread);
    }

    address owner = NULL;
    {
      markOop mark = hobj()->mark();

      if (!mark->has_monitor()) {
        // this object has a lightweight monitor

        if (mark->has_locker()) {
          owner = (address)mark->locker(); // save the address of the Lock word
        }
        // implied else: no owner
      } else {
        // this object has a heavyweight monitor
        mon = mark->monitor();

        // The owner field of a heavyweight monitor may be NULL for no
        // owner, a JavaThread * or it may still be the address of the
        // Lock word in a JavaThread's stack. A monitor can be inflated
        // by a non-owning JavaThread, but only the owning JavaThread
        // can change the owner field from the Lock word to the
        // JavaThread * and it may not have done that yet.
        owner = (address)mon->owner();
      }
    }

    if (owner != NULL) {
      // This monitor is owned so we have to find the owning JavaThread.
      // Since owning_thread_from_monitor_owner() grabs a lock, GC can
      // 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 *.
      owning_thread = Threads::owning_thread_from_monitor_owner(owner, !at_safepoint);
      // Cannot assume (owning_thread != NULL) here because this function
      // 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
        // or it has to be suspended. Any of these conditions will prevent both
        // contending and waiting threads from modifying the state of
        // the monitor.
        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;
        }
        HandleMark hm;
        Handle     th(owning_thread->threadObj());
        ret.owner = (jthread)jni_reference(calling_thread, th);
      }
      // implied else: no owner
    }

    if (owning_thread != NULL) {  // monitor is owned
      // The recursions field of a monitor does not reflect recursions
      // as lightweight locks before inflating the monitor are not included.
      // We have to count the number of recursive monitor entries the hard way.
      // We pass a handle to survive any GCs along the way.
      ResourceMark rm;
      ret.entry_count = count_locked_objects(owning_thread, hobj);
    }
    // implied else: entry_count == 0
  }

  jint nWant, nWait;
  if (mon != NULL) {
    // this object has a heavyweight monitor
    nWant = mon->contentions(); // # of threads contending for monitor
    nWait = mon->waiters();     // # of threads in Object.wait()
    ret.waiter_count = nWant + nWait;
    ret.notify_waiter_count = nWait;
  } else {
    // this object has a lightweight monitor
    ret.waiter_count = 0;
    ret.notify_waiter_count = 0;
  }

  // Allocate memory for heavyweight and lightweight monitor.
  jvmtiError err;
  err = allocate(ret.waiter_count * sizeof(jthread *), (unsigned char**)&ret.waiters);
  if (err != JVMTI_ERROR_NONE) {
    return err;
  }
  err = allocate(ret.notify_waiter_count * sizeof(jthread *),
                 (unsigned char**)&ret.notify_waiters);
  if (err != JVMTI_ERROR_NONE) {
    deallocate((unsigned char*)ret.waiters);
    return err;
  }

  // now derive the rest of the fields
  if (mon != NULL) {
    // this object has a heavyweight monitor

    // Number of waiters may actually be less than the waiter count.
    // So NULL out memory so that unused memory will be NULL.
    memset(ret.waiters, 0, ret.waiter_count * sizeof(jthread *));
    memset(ret.notify_waiters, 0, ret.notify_waiter_count * sizeof(jthread *));

    if (ret.waiter_count > 0) {
      // we have contending and/or waiting threads
      HandleMark hm;
      if (nWant > 0) {
        // we have contending threads
        ResourceMark rm;
        // get_pending_threads returns only java thread so we do not need to
        // check for  non java threads.
        GrowableArray<JavaThread*>* wantList = Threads::get_pending_threads(
          nWant, (address)mon, !at_safepoint);
        if (wantList->length() < nWant) {
          // robustness: the pending list has gotten smaller
          nWant = wantList->length();
        }
        for (int i = 0; i < nWant; i++) {
          JavaThread *pending_thread = wantList->at(i);
          // If the monitor has no owner, then a non-suspended contending
          // thread could potentially change the state of the monitor by
          // entering it. The JVM/TI spec doesn't allow this.
          if (owning_thread == NULL && !at_safepoint &
              !JvmtiEnv::is_thread_fully_suspended(pending_thread, true, &debug_bits)) {
            if (ret.owner != NULL) {
              destroy_jni_reference(calling_thread, ret.owner);
            }
            for (int j = 0; j < i; j++) {
              destroy_jni_reference(calling_thread, ret.waiters[j]);
            }
            deallocate((unsigned char*)ret.waiters);
            deallocate((unsigned char*)ret.notify_waiters);
            return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
          }
          Handle th(pending_thread->threadObj());
          ret.waiters[i] = (jthread)jni_reference(calling_thread, th);
        }
      }
      if (nWait > 0) {
        // we have threads in Object.wait()
        int offset = nWant;  // add after any contending threads
        ObjectWaiter *waiter = mon->first_waiter();
        for (int i = 0, j = 0; i < nWait; i++) {
          if (waiter == NULL) {
            // robustness: the waiting list has gotten smaller
            nWait = j;
            break;
          }
          Thread *t = mon->thread_of_waiter(waiter);
          if (t != NULL && t->is_Java_thread()) {
            JavaThread *wjava_thread = (JavaThread *)t;
            // If the thread was found on the ObjectWaiter list, then
            // it has not been notified. This thread can't change the
            // state of the monitor so it doesn't need to be suspended.
            Handle th(wjava_thread->threadObj());
            ret.waiters[offset + j] = (jthread)jni_reference(calling_thread, th);
            ret.notify_waiters[j++] = (jthread)jni_reference(calling_thread, th);
          }
          waiter = mon->next_waiter(waiter);
        }
      }
    }

    // Adjust count. nWant and nWait count values may be less than original.
    ret.waiter_count = nWant + nWait;
    ret.notify_waiter_count = nWait;
  } else {
    // this object has a lightweight monitor and we have nothing more
    // to do here because the defaults are just fine.
  }

  // we don't update return parameter unless everything worked
  *info_ptr = ret;

  return JVMTI_ERROR_NONE;
}
Exemple #6
0
// Save JNI local handles for any objects that this frame owns.
jvmtiError
JvmtiEnvBase::get_locked_objects_in_frame(JavaThread* calling_thread, JavaThread* java_thread,
                                 javaVFrame *jvf, GrowableArray<jvmtiMonitorStackDepthInfo*>* owned_monitors_list, int stack_depth) {
  jvmtiError err = JVMTI_ERROR_NONE;
  ResourceMark rm;

  GrowableArray<MonitorInfo*>* mons = jvf->monitors();
  if (mons->is_empty()) {
    return err;  // this javaVFrame holds no monitors
  }

  HandleMark hm;
  oop wait_obj = NULL;
  {
    // save object of current wait() call (if any) for later comparison
    ObjectMonitor *mon = java_thread->current_waiting_monitor();
    if (mon != NULL) {
      wait_obj = (oop)mon->object();
    }
  }
  oop pending_obj = NULL;
  {
    // save object of current enter() call (if any) for later comparison
    ObjectMonitor *mon = java_thread->current_pending_monitor();
    if (mon != NULL) {
      pending_obj = (oop)mon->object();
    }
  }

  for (int i = 0; i < mons->length(); i++) {
    MonitorInfo *mi = mons->at(i);

    if (mi->owner_is_scalar_replaced()) continue;

    oop obj = mi->owner();
    if (obj == NULL) {
      // this monitor doesn't have an owning object so skip it
      continue;
    }

    if (wait_obj == obj) {
      // the thread is waiting on this monitor so it isn't really owned
      continue;
    }

    if (pending_obj == obj) {
      // the thread is pending on this monitor so it isn't really owned
      continue;
    }

    if (owned_monitors_list->length() > 0) {
      // Our list has at least one object on it so we have to check
      // for recursive object locking
      bool found = false;
      for (int j = 0; j < owned_monitors_list->length(); j++) {
        jobject jobj = ((jvmtiMonitorStackDepthInfo*)owned_monitors_list->at(j))->monitor;
        oop check = JNIHandles::resolve(jobj);
        if (check == obj) {
          found = true;  // we found the object
          break;
        }
      }

      if (found) {
        // already have this object so don't include it
        continue;
      }
    }

    // add the owning object to our list
    jvmtiMonitorStackDepthInfo *jmsdi;
    err = allocate(sizeof(jvmtiMonitorStackDepthInfo), (unsigned char **)&jmsdi);
    if (err != JVMTI_ERROR_NONE) {
        return err;
    }
    Handle hobj(obj);
    jmsdi->monitor = jni_reference(calling_thread, hobj);
    jmsdi->stack_depth = stack_depth;
    owned_monitors_list->append(jmsdi);
  }

  return err;
}
// Save global JNI handles for any objects that this thread owns.
void javaVFrame::save_lock_entries(GrowableArray<jobject>* handle_list) {
  ResourceMark rm;

  GrowableArray<MonitorInfo*>* mons = monitors();
  if (mons->is_empty()) {
    return;  // this javaVFrame holds no monitors
  }

  HandleMark hm;
  oop wait_obj = NULL;
  {
    // save object of current wait() call (if any) for later comparison
    ObjectMonitor *mon = thread()->current_waiting_monitor();
    if (mon != NULL) {
      wait_obj = (oop)mon->object();
    }
  }
  oop pending_obj = NULL;
  {
    // save object of current enter() call (if any) for later comparison
    ObjectMonitor *mon = thread()->current_pending_monitor();
    if (mon != NULL) {
      pending_obj = (oop)mon->object();
    }
  }

  for (int i = 0; i < mons->length(); i++) {
    MonitorInfo *mi = mons->at(i);

    oop obj = mi->owner();
    if (obj == NULL) {
      // this monitor doesn't have an owning object so skip it
      continue;
    }

    if (wait_obj == obj) {
      // the thread is waiting on this monitor so it isn't really owned
      continue;
    }

    if (pending_obj == obj) {
      // the thread is pending on this monitor so it isn't really owned
      continue;
    }

    if (handle_list->length() > 0) {
      // Our list has at least one object on it so we have to check
      // for recursive object locking
      bool found = false;
      for (int j = 0; j < handle_list->length(); j++) {
        jobject jobj = handle_list->at(j);
        oop check = JNIHandles::resolve(jobj);
        if (check == obj) {
          found = true;  // we found the object
          break;
        }
      }

      if (found) {
        // already have this object so don't include it
        continue;
      }
    }

    // add the owning object to our list
    Handle hobj(obj);
    jobject jobj = (jobject)JNIHandles::make_global(hobj);
    handle_list->append(jobj);
  }
}
Exemple #8
0
// Find deadlocks involving object monitors and concurrent locks if concurrent_locks is true
DeadlockCycle* ThreadService::find_deadlocks_at_safepoint(bool concurrent_locks) {
  // This code was modified from the original Threads::find_deadlocks code.
  int globalDfn = 0, thisDfn;
  ObjectMonitor* waitingToLockMonitor = NULL;
  oop waitingToLockBlocker = NULL;
  bool blocked_on_monitor = false;
  JavaThread *currentThread, *previousThread;
  int num_deadlocks = 0;

  for (JavaThread* p = Threads::first(); p != NULL; p = p->next()) {
    // Initialize the depth-first-number
    p->set_depth_first_number(-1);
  }

  DeadlockCycle* deadlocks = NULL;
  DeadlockCycle* last = NULL;
  DeadlockCycle* cycle = new DeadlockCycle();
  for (JavaThread* jt = Threads::first(); jt != NULL; jt = jt->next()) {
    if (jt->depth_first_number() >= 0) {
      // this thread was already visited
      continue;
    }

    thisDfn = globalDfn;
    jt->set_depth_first_number(globalDfn++);
    previousThread = jt;
    currentThread = jt;

    cycle->reset();

    // When there is a deadlock, all the monitors involved in the dependency
    // cycle must be contended and heavyweight. So we only care about the
    // heavyweight monitor a thread is waiting to lock.
    waitingToLockMonitor = (ObjectMonitor*)jt->current_pending_monitor();
    if (concurrent_locks) {
      waitingToLockBlocker = jt->current_park_blocker();
    }
    while (waitingToLockMonitor != NULL || waitingToLockBlocker != NULL) {
      cycle->add_thread(currentThread);
      if (waitingToLockMonitor != NULL) {
        address currentOwner = (address)waitingToLockMonitor->owner();
        if (currentOwner != NULL) {
          currentThread = Threads::owning_thread_from_monitor_owner(
                            currentOwner,
                            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 {
        if (concurrent_locks) {
          if (waitingToLockBlocker->is_a(SystemDictionary::abstract_ownable_synchronizer_klass())) {
            oop threadObj = java_util_concurrent_locks_AbstractOwnableSynchronizer::get_owner_threadObj(waitingToLockBlocker);
            currentThread = threadObj != NULL ? java_lang_Thread::thread(threadObj) : NULL;
          } else {
            currentThread = NULL;
          }
        }
      }

      if (currentThread == NULL) {
        // No dependency on another thread
        break;
      }
      if (currentThread->depth_first_number() < 0) {
        // First visit to this thread
        currentThread->set_depth_first_number(globalDfn++);
      } else if (currentThread->depth_first_number() < thisDfn) {
        // Thread already visited, and not on a (new) cycle
        break;
      } else if (currentThread == previousThread) {
        // Self-loop, ignore
        break;
      } else {
        // We have a (new) cycle
        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;
      }
      previousThread = currentThread;
      waitingToLockMonitor = (ObjectMonitor*)currentThread->current_pending_monitor();
      if (concurrent_locks) {
        waitingToLockBlocker = currentThread->current_park_blocker();
      }
    }

  }
  delete cycle;
  return deadlocks;
}