8309613: [Windows] hs_err files sometimes miss information about the code containing the error
Reviewed-by: dholmes, stuefe
This commit is contained in:
parent
63fe413d93
commit
bd79db3930
@ -172,7 +172,7 @@ class os::Aix {
|
|||||||
// Returns true if ok, false if error.
|
// Returns true if ok, false if error.
|
||||||
static bool get_meminfo(meminfo_t* pmi);
|
static bool get_meminfo(meminfo_t* pmi);
|
||||||
|
|
||||||
static bool platform_print_native_stack(outputStream* st, const void* context, char *buf, int buf_size);
|
static bool platform_print_native_stack(outputStream* st, const void* context, char *buf, int buf_size, address& lastpc);
|
||||||
static void* resolve_function_descriptor(void* p);
|
static void* resolve_function_descriptor(void* p);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ class os::win32 {
|
|||||||
static void print_uptime_info(outputStream* st);
|
static void print_uptime_info(outputStream* st);
|
||||||
|
|
||||||
static bool platform_print_native_stack(outputStream* st, const void* context,
|
static bool platform_print_native_stack(outputStream* st, const void* context,
|
||||||
char *buf, int buf_size);
|
char *buf, int buf_size, address& lastpc);
|
||||||
|
|
||||||
static bool register_code_area(char *low, char *high);
|
static bool register_code_area(char *low, char *high);
|
||||||
|
|
||||||
|
@ -516,7 +516,7 @@ int os::extra_bang_size_in_bytes() {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool os::Aix::platform_print_native_stack(outputStream* st, const void* context, char *buf, int buf_size) {
|
bool os::Aix::platform_print_native_stack(outputStream* st, const void* context, char *buf, int buf_size, address& lastpc) {
|
||||||
AixNativeCallstack::print_callstack_for_context(st, (const ucontext_t*)context, true, buf, (size_t) buf_size);
|
AixNativeCallstack::print_callstack_for_context(st, (const ucontext_t*)context, true, buf, (size_t) buf_size);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -30,8 +30,8 @@
|
|||||||
|
|
||||||
#define HAVE_PLATFORM_PRINT_NATIVE_STACK 1
|
#define HAVE_PLATFORM_PRINT_NATIVE_STACK 1
|
||||||
inline bool os::platform_print_native_stack(outputStream* st, const void* context,
|
inline bool os::platform_print_native_stack(outputStream* st, const void* context,
|
||||||
char *buf, int buf_size) {
|
char *buf, int buf_size, address& lastpc) {
|
||||||
return os::Aix::platform_print_native_stack(st, context, buf, buf_size);
|
return os::Aix::platform_print_native_stack(st, context, buf, buf_size, lastpc);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define HAVE_FUNCTION_DESCRIPTORS 1
|
#define HAVE_FUNCTION_DESCRIPTORS 1
|
||||||
|
@ -224,7 +224,7 @@ bool os::win32::register_code_area(char *low, char *high) {
|
|||||||
* loop in vmError.cpp. We need to roll our own loop.
|
* loop in vmError.cpp. We need to roll our own loop.
|
||||||
*/
|
*/
|
||||||
bool os::win32::platform_print_native_stack(outputStream* st, const void* context,
|
bool os::win32::platform_print_native_stack(outputStream* st, const void* context,
|
||||||
char *buf, int buf_size)
|
char *buf, int buf_size, address& lastpc)
|
||||||
{
|
{
|
||||||
CONTEXT ctx;
|
CONTEXT ctx;
|
||||||
if (context != nullptr) {
|
if (context != nullptr) {
|
||||||
@ -245,14 +245,14 @@ bool os::win32::platform_print_native_stack(outputStream* st, const void* contex
|
|||||||
stk.AddrPC.Mode = AddrModeFlat;
|
stk.AddrPC.Mode = AddrModeFlat;
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
address lastpc = 0;
|
address lastpc_internal = 0;
|
||||||
while (count++ < StackPrintLimit) {
|
while (count++ < StackPrintLimit) {
|
||||||
intptr_t* sp = (intptr_t*)stk.AddrStack.Offset;
|
intptr_t* sp = (intptr_t*)stk.AddrStack.Offset;
|
||||||
intptr_t* fp = (intptr_t*)stk.AddrFrame.Offset; // NOT necessarily the same as ctx.Rbp!
|
intptr_t* fp = (intptr_t*)stk.AddrFrame.Offset; // NOT necessarily the same as ctx.Rbp!
|
||||||
address pc = (address)stk.AddrPC.Offset;
|
address pc = (address)stk.AddrPC.Offset;
|
||||||
|
|
||||||
if (pc != nullptr) {
|
if (pc != nullptr) {
|
||||||
if (count == 2 && lastpc == pc) {
|
if (count == 2 && lastpc_internal == pc) {
|
||||||
// Skip it -- StackWalk64() may return the same PC
|
// Skip it -- StackWalk64() may return the same PC
|
||||||
// (but different SP) on the first try.
|
// (but different SP) on the first try.
|
||||||
} else {
|
} else {
|
||||||
@ -268,12 +268,13 @@ bool os::win32::platform_print_native_stack(outputStream* st, const void* contex
|
|||||||
}
|
}
|
||||||
st->cr();
|
st->cr();
|
||||||
}
|
}
|
||||||
lastpc = pc;
|
lastpc_internal = pc;
|
||||||
}
|
}
|
||||||
|
|
||||||
PVOID p = WindowsDbgHelp::symFunctionTableAccess64(GetCurrentProcess(), stk.AddrPC.Offset);
|
PVOID p = WindowsDbgHelp::symFunctionTableAccess64(GetCurrentProcess(), stk.AddrPC.Offset);
|
||||||
if (!p) {
|
if (!p) {
|
||||||
// StackWalk64() can't handle this PC. Calling StackWalk64 again may cause crash.
|
// StackWalk64() can't handle this PC. Calling StackWalk64 again may cause crash.
|
||||||
|
lastpc = lastpc_internal;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,8 +31,8 @@
|
|||||||
#ifdef AMD64
|
#ifdef AMD64
|
||||||
#define HAVE_PLATFORM_PRINT_NATIVE_STACK 1
|
#define HAVE_PLATFORM_PRINT_NATIVE_STACK 1
|
||||||
inline bool os::platform_print_native_stack(outputStream* st, const void* context,
|
inline bool os::platform_print_native_stack(outputStream* st, const void* context,
|
||||||
char *buf, int buf_size) {
|
char *buf, int buf_size, address& lastpc) {
|
||||||
return os::win32::platform_print_native_stack(st, context, buf, buf_size);
|
return os::win32::platform_print_native_stack(st, context, buf, buf_size, lastpc);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1008,7 +1008,7 @@ class os: AllStatic {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
inline static bool platform_print_native_stack(outputStream* st, const void* context,
|
inline static bool platform_print_native_stack(outputStream* st, const void* context,
|
||||||
char *buf, int buf_size);
|
char *buf, int buf_size, address& lastpc);
|
||||||
|
|
||||||
// debugging support (mostly used by debug.cpp but also fatal error handler)
|
// debugging support (mostly used by debug.cpp but also fatal error handler)
|
||||||
static bool find(address pc, outputStream* st = tty); // OS specific function to make sense out of an address
|
static bool find(address pc, outputStream* st = tty); // OS specific function to make sense out of an address
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
|
|
||||||
#ifndef HAVE_PLATFORM_PRINT_NATIVE_STACK
|
#ifndef HAVE_PLATFORM_PRINT_NATIVE_STACK
|
||||||
inline bool os::platform_print_native_stack(outputStream* st, const void* context,
|
inline bool os::platform_print_native_stack(outputStream* st, const void* context,
|
||||||
char *buf, int buf_size) {
|
char *buf, int buf_size, address& lastpc) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -654,7 +654,8 @@ extern "C" JNIEXPORT void pns(void* sp, void* fp, void* pc) { // print native st
|
|||||||
extern "C" JNIEXPORT void pns2() { // print native stack
|
extern "C" JNIEXPORT void pns2() { // print native stack
|
||||||
Command c("pns2");
|
Command c("pns2");
|
||||||
static char buf[O_BUFLEN];
|
static char buf[O_BUFLEN];
|
||||||
if (os::platform_print_native_stack(tty, nullptr, buf, sizeof(buf))) {
|
address lastpc = nullptr;
|
||||||
|
if (os::platform_print_native_stack(tty, nullptr, buf, sizeof(buf), lastpc)) {
|
||||||
// We have printed the native stack in platform-specific code,
|
// We have printed the native stack in platform-specific code,
|
||||||
// so nothing else to do in this case.
|
// so nothing else to do in this case.
|
||||||
} else {
|
} else {
|
||||||
|
@ -387,6 +387,27 @@ static bool print_code(outputStream* st, Thread* thread, address pc, bool is_cra
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Like above, but only try to figure out a short name. Return nullptr if not found.
|
||||||
|
static const char* find_code_name(address pc) {
|
||||||
|
if (Interpreter::contains(pc)) {
|
||||||
|
InterpreterCodelet* codelet = Interpreter::codelet_containing(pc);
|
||||||
|
if (codelet != nullptr) {
|
||||||
|
return codelet->description();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
StubCodeDesc* desc = StubCodeDesc::desc_for(pc);
|
||||||
|
if (desc != nullptr) {
|
||||||
|
return desc->name();
|
||||||
|
} else {
|
||||||
|
CodeBlob* cb = CodeCache::find_blob(pc);
|
||||||
|
if (cb != nullptr) {
|
||||||
|
return cb->name();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the caller frame of `fr`.
|
* Gets the caller frame of `fr`.
|
||||||
*
|
*
|
||||||
@ -675,6 +696,10 @@ void VMError::report(outputStream* st, bool _verbose) {
|
|||||||
// don't allocate large buffer on stack
|
// don't allocate large buffer on stack
|
||||||
static char buf[O_BUFLEN];
|
static char buf[O_BUFLEN];
|
||||||
|
|
||||||
|
// Native stack trace may get stuck. We try to handle the last pc if it
|
||||||
|
// belongs to VM generated code.
|
||||||
|
address lastpc = nullptr;
|
||||||
|
|
||||||
BEGIN
|
BEGIN
|
||||||
|
|
||||||
STEP("printing fatal error message")
|
STEP("printing fatal error message")
|
||||||
@ -963,9 +988,16 @@ void VMError::report(outputStream* st, bool _verbose) {
|
|||||||
st->cr();
|
st->cr();
|
||||||
|
|
||||||
STEP_IF("printing native stack (with source info)", _verbose)
|
STEP_IF("printing native stack (with source info)", _verbose)
|
||||||
if (os::platform_print_native_stack(st, _context, buf, sizeof(buf))) {
|
if (os::platform_print_native_stack(st, _context, buf, sizeof(buf), lastpc)) {
|
||||||
// We have printed the native stack in platform-specific code
|
// We have printed the native stack in platform-specific code
|
||||||
// Windows/x64 needs special handling.
|
// Windows/x64 needs special handling.
|
||||||
|
// Stack walking may get stuck. Try to find the calling code.
|
||||||
|
if (lastpc != nullptr) {
|
||||||
|
const char* name = find_code_name(lastpc);
|
||||||
|
if (name != nullptr) {
|
||||||
|
st->print_cr("The last pc belongs to %s (printed below).", name);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
frame fr = _context ? os::fetch_frame_from_context(_context)
|
frame fr = _context ? os::fetch_frame_from_context(_context)
|
||||||
: os::current_frame();
|
: os::current_frame();
|
||||||
@ -1070,6 +1102,13 @@ void VMError::report(outputStream* st, bool _verbose) {
|
|||||||
// value outside the range.
|
// value outside the range.
|
||||||
int limit = MIN2(ErrorLogPrintCodeLimit, printed_capacity);
|
int limit = MIN2(ErrorLogPrintCodeLimit, printed_capacity);
|
||||||
if (limit > 0) {
|
if (limit > 0) {
|
||||||
|
// Check if a pc was found by native stack trace above.
|
||||||
|
if (lastpc != nullptr) {
|
||||||
|
if (print_code(st, _thread, lastpc, true, printed, printed_capacity)) {
|
||||||
|
printed_len++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Scan the native stack
|
// Scan the native stack
|
||||||
if (!_print_native_stack_used) {
|
if (!_print_native_stack_used) {
|
||||||
// Only try to print code of the crashing frame since
|
// Only try to print code of the crashing frame since
|
||||||
|
Loading…
x
Reference in New Issue
Block a user