提交 db7b5bb8 编写于 作者: C coleenp

Merge

/*
* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -25,6 +25,13 @@
#include <jni.h>
#include "libproc.h"
#include <elf.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <limits.h>
#if defined(x86_64) && !defined(amd64)
#define amd64 1
#endif
......@@ -154,6 +161,39 @@ static void fillThreadsAndLoadObjects(JNIEnv* env, jobject this_obj, struct ps_p
}
}
/*
* Verify that a named ELF binary file (core or executable) has the same
* bitness as ourselves.
* Throw an exception if there is a mismatch or other problem.
*
* If we proceed using a mismatched debugger/debuggee, the best to hope
* for is a missing symbol, the worst is a crash searching for debug symbols.
*/
void verifyBitness(JNIEnv *env, const char *binaryName) {
int fd = open(binaryName, O_RDONLY);
if (fd < 0) {
THROW_NEW_DEBUGGER_EXCEPTION("cannot open binary file");
}
unsigned char elf_ident[EI_NIDENT];
int i = read(fd, &elf_ident, sizeof(elf_ident));
close(fd);
if (i < 0) {
THROW_NEW_DEBUGGER_EXCEPTION("cannot read binary file");
}
#ifndef _LP64
if (elf_ident[EI_CLASS] == ELFCLASS64) {
THROW_NEW_DEBUGGER_EXCEPTION("debuggee is 64 bit, use 64-bit java for debugger");
}
#else
if (elf_ident[EI_CLASS] != ELFCLASS64) {
THROW_NEW_DEBUGGER_EXCEPTION("debuggee is 32 bit, use 32 bit java for debugger");
}
#endif
}
/*
* Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal
* Method: attach0
......@@ -162,6 +202,12 @@ static void fillThreadsAndLoadObjects(JNIEnv* env, jobject this_obj, struct ps_p
JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_attach0__I
(JNIEnv *env, jobject this_obj, jint jpid) {
// For bitness checking, locate binary at /proc/jpid/exe
char buf[PATH_MAX];
snprintf((char *) &buf, PATH_MAX, "/proc/%d/exe", jpid);
verifyBitness(env, (char *) &buf);
CHECK_EXCEPTION;
struct ps_prochandle* ph;
if ( (ph = Pgrab(jpid)) == NULL) {
THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the process");
......@@ -187,6 +233,9 @@ JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_at
coreName_cstr = (*env)->GetStringUTFChars(env, coreName, &isCopy);
CHECK_EXCEPTION;
verifyBitness(env, execName_cstr);
CHECK_EXCEPTION;
if ( (ph = Pgrab_core(execName_cstr, coreName_cstr)) == NULL) {
(*env)->ReleaseStringUTFChars(env, execName, execName_cstr);
(*env)->ReleaseStringUTFChars(env, coreName, coreName_cstr);
......
......@@ -60,8 +60,13 @@ final public class LinuxAMD64CFrame extends BasicCFrame {
return null;
}
// Check alignment of rbp
if ( dbg.getAddressValue(rbp) % ADDRESS_SIZE != 0) {
return null;
}
Address nextRBP = rbp.getAddressAt( 0 * ADDRESS_SIZE);
if (nextRBP == null) {
if (nextRBP == null || nextRBP.lessThanOrEqual(rbp)) {
return null;
}
Address nextPC = rbp.getAddressAt( 1 * ADDRESS_SIZE);
......
......@@ -61,8 +61,13 @@ final public class LinuxX86CFrame extends BasicCFrame {
return null;
}
// Check alignment of ebp
if ( dbg.getAddressValue(ebp) % ADDRESS_SIZE != 0) {
return null;
}
Address nextEBP = ebp.getAddressAt( 0 * ADDRESS_SIZE);
if (nextEBP == null) {
if (nextEBP == null || nextEBP.lessThanOrEqual(ebp)) {
return null;
}
Address nextPC = ebp.getAddressAt( 1 * ADDRESS_SIZE);
......
......@@ -308,27 +308,6 @@ ByteSize FrameMap::sp_offset_for_monitor_object(int index) const {
return sp_offset_for_monitor_base(index) + in_ByteSize(BasicObjectLock::obj_offset_in_bytes());
}
void FrameMap::print_frame_layout() const {
int svar;
tty->print_cr("#####################################");
tty->print_cr("Frame size in words %d", framesize());
if( _num_monitors > 0) {
tty->print_cr("monitor [0]:%d | [%2d]:%d",
in_bytes(sp_offset_for_monitor_base(0)),
in_bytes(sp_offset_for_monitor_base(_num_monitors)));
}
if( _num_spills > 0) {
svar = _num_spills - 1;
if(svar == 0)
tty->print_cr("spill [0]:%d", in_bytes(sp_offset_for_spill(0)));
else
tty->print_cr("spill [0]:%d | [%2d]:%d", in_bytes(sp_offset_for_spill(0)),
svar,
in_bytes(sp_offset_for_spill(svar)));
}
}
// For OopMaps, map a local variable or spill index to an VMReg.
// This is the offset from sp() in the frame of the slot for the index,
......
......@@ -226,8 +226,6 @@ class FrameMap : public CompilationResourceObj {
return make_new_address(sp_offset_for_monitor_object(monitor_index));
}
void print_frame_layout() const;
// Creates Location describing desired slot and returns it via pointer
// to Location object. Returns true if the stack frame offset was legal
// (as defined by Location::legal_offset_in_bytes()), false otherwise.
......
......@@ -373,6 +373,8 @@ process_chunk_boundaries(Space* sp,
" does not exceed used.end() = " PTR_FORMAT ","
" yet last_chunk_index_to_check " INTPTR_FORMAT
" exceeds last_chunk_index " INTPTR_FORMAT,
last_block, last_block + last_block_size,
used.end(),
last_chunk_index_to_check, last_chunk_index));
assert(sp->used_region().end() > used.end(),
err_msg("Expansion did not happen: "
......
......@@ -694,7 +694,7 @@ void CardTableModRefBS::verify_region(MemRegion mr,
if (failed) {
if (!failures) {
tty->cr();
tty->print_cr("== CT verification failed: ["PTR_FORMAT","PTR_FORMAT"]");
tty->print_cr("== CT verification failed: ["PTR_FORMAT","PTR_FORMAT"]", start, end);
tty->print_cr("== %sexpecting value: %d",
(val_equals) ? "" : "not ", val);
failures = true;
......
......@@ -353,7 +353,7 @@ protected:
assert(jp >= _begin && jp < _end,
err_msg("Error: jp " PTR_FORMAT " should be within "
"[_begin, _end) = [" PTR_FORMAT "," PTR_FORMAT ")",
_begin, _end));
jp, _begin, _end));
oop obj = oopDesc::load_decode_heap_oop(p);
guarantee(obj == NULL || (HeapWord*)obj >= _boundary,
err_msg("pointer " PTR_FORMAT " at " PTR_FORMAT " on "
......
......@@ -773,7 +773,7 @@ static jvmtiError JNICALL
</xsl:text>
<xsl:apply-templates select=".." mode="traceError">
<xsl:with-param name="err">JVMTI_ERROR_INVALID_THREAD</xsl:with-param>
<xsl:with-param name="comment"> - jthread resolved to NULL - jthread = %0x%x</xsl:with-param>
<xsl:with-param name="comment"> - jthread resolved to NULL - jthread = 0x%x</xsl:with-param>
<xsl:with-param name="extraValue">, <xsl:value-of select="$name"/></xsl:with-param>
</xsl:apply-templates>
<xsl:text>
......@@ -782,7 +782,7 @@ static jvmtiError JNICALL
</xsl:text>
<xsl:apply-templates select=".." mode="traceError">
<xsl:with-param name="err">JVMTI_ERROR_INVALID_THREAD</xsl:with-param>
<xsl:with-param name="comment"> - oop is not a thread - jthread = %0x%x</xsl:with-param>
<xsl:with-param name="comment"> - oop is not a thread - jthread = 0x%x</xsl:with-param>
<xsl:with-param name="extraValue">, <xsl:value-of select="$name"/></xsl:with-param>
</xsl:apply-templates>
<xsl:text>
......@@ -794,7 +794,7 @@ static jvmtiError JNICALL
<xsl:with-param name="err">
<xsl:text>JVMTI_ERROR_THREAD_NOT_ALIVE</xsl:text>
</xsl:with-param>
<xsl:with-param name="comment"> - not a Java thread - jthread = %0x%x</xsl:with-param>
<xsl:with-param name="comment"> - not a Java thread - jthread = 0x%x</xsl:with-param>
<xsl:with-param name="extraValue">, <xsl:value-of select="$name"/></xsl:with-param>
</xsl:apply-templates>
<xsl:text>
......@@ -838,7 +838,7 @@ static jvmtiError JNICALL
</xsl:text>
<xsl:apply-templates select=".." mode="traceError">
<xsl:with-param name="err">JVMTI_ERROR_ILLEGAL_ARGUMENT</xsl:with-param>
<xsl:with-param name="comment"> - negative depth - jthread = %0x%x</xsl:with-param>
<xsl:with-param name="comment"> - negative depth - jthread = 0x%x</xsl:with-param>
<xsl:with-param name="extraValue">, <xsl:value-of select="$name"/></xsl:with-param>
</xsl:apply-templates>
<xsl:text>
......
......@@ -997,13 +997,19 @@ JvmtiEnvBase::get_object_monitor_usage(JavaThread* calling_thread, jobject objec
// move our object at this point. However, our owner value is safe
// since it is either the Lock word on a stack or a JavaThread *.
owning_thread = Threads::owning_thread_from_monitor_owner(owner, !at_safepoint);
assert(owning_thread != NULL, "sanity check");
if (owning_thread != NULL) { // robustness
// 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;
......
......@@ -813,6 +813,7 @@ JavaThread* ObjectSynchronizer::get_lock_owner(Handle h_obj, bool doLock) {
}
if (owner != NULL) {
// owning_thread_from_monitor_owner() may also return NULL here
return Threads::owning_thread_from_monitor_owner(owner, doLock);
}
......
......@@ -4285,7 +4285,9 @@ JavaThread *Threads::owning_thread_from_monitor_owner(address owner, bool doLock
if (owner == (address)p) return p;
}
}
assert(UseHeavyMonitors == false, "Did not find owning Java thread with UseHeavyMonitors enabled");
// Cannot assert on lack of success here since this function may be
// used by code that is trying to report useful problem information
// like deadlock detection.
if (UseHeavyMonitors) return NULL;
//
......@@ -4303,7 +4305,7 @@ JavaThread *Threads::owning_thread_from_monitor_owner(address owner, bool doLock
}
}
}
assert(the_owner != NULL, "Did not find owning Java thread for lock word address");
// cannot assert on lack of success here; see above comment
return the_owner;
}
......
......@@ -419,7 +419,7 @@ void BaselineTTYOutputer::virtual_memory_callsite(address pc, size_t reserved_am
_output->print_cr("[" PTR_FORMAT "] %s+0x%x", pc, buf, offset);
_output->print("%28s", " ");
} else {
_output->print("[" PTR_FORMAT "]%18s", " ");
_output->print("[" PTR_FORMAT "]%18s", pc, " ");
}
_output->print_cr("(mmap: reserved=%d%s, committed=%d%s)",
......@@ -596,7 +596,7 @@ void BaselineTTYOutputer::diff_virtual_memory_callsite(address pc,
_output->print_cr("[" PTR_FORMAT "] %s+0x%x", pc, buf, offset);
_output->print("%28s", " ");
} else {
_output->print("[" PTR_FORMAT "]%18s", " ");
_output->print("[" PTR_FORMAT "]%18s", pc, " ");
}
}
......
/*
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -327,8 +327,28 @@ DeadlockCycle* ThreadService::find_deadlocks_at_safepoint(bool concurrent_locks)
while (waitingToLockMonitor != NULL || waitingToLockBlocker != NULL) {
cycle->add_thread(currentThread);
if (waitingToLockMonitor != NULL) {
currentThread = Threads::owning_thread_from_monitor_owner((address)waitingToLockMonitor->owner(),
false /* no locking needed */);
currentThread = Threads::owning_thread_from_monitor_owner(
(address)waitingToLockMonitor->owner(),
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())) {
......@@ -841,7 +861,17 @@ void DeadlockCycle::print_on(outputStream* st) const {
owner_desc = " (JVMTI raw monitor),\n which is held by";
}
currentThread = Threads::owning_thread_from_monitor_owner(
(address)waitingToLockMonitor->owner(), false /* no locking needed */);
(address)waitingToLockMonitor->owner(),
false /* no locking needed */);
if (currentThread == NULL) {
// The deadlock was detected at a safepoint so the JavaThread
// that owns waitingToLockMonitor should be findable, but
// if it is not findable, then the previous currentThread is
// blocked permanently.
st->print("%s UNKNOWN_owner_addr=" PTR_FORMAT, owner_desc,
(address)waitingToLockMonitor->owner());
continue;
}
} else {
st->print(" waiting for ownable synchronizer " INTPTR_FORMAT ", (a %s)",
(address)waitingToLockBlocker,
......
......@@ -245,7 +245,7 @@ void AbsSeq::dump_on(outputStream* s) {
void NumberSeq::dump_on(outputStream* s) {
AbsSeq::dump_on(s);
s->print_cr("\t\t _last = %7.3f, _maximum = %7.3f");
s->print_cr("\t\t _last = %7.3f, _maximum = %7.3f", _last, _maximum);
}
void TruncatedSeq::dump_on(outputStream* s) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册