Skip to content

Commit

Permalink
8309613: [Windows] hs_err files sometimes miss information about the …
Browse files Browse the repository at this point in the history
…code containing the error

Reviewed-by: phh
Backport-of: bd79db3930f192f6742e29a63a6d1c3bc3dd3385
  • Loading branch information
TheRealMDoerr committed Jun 23, 2023
1 parent bd0e479 commit 8dae82c
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 10 deletions.
2 changes: 1 addition & 1 deletion src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,7 @@ int os::extra_bang_size_in_bytes() {
return 0;
}

bool os::platform_print_native_stack(outputStream* st, void* context, char *buf, int buf_size) {
bool os::platform_print_native_stack(outputStream* st, 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);
return true;
}
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/os_cpu/aix_ppc/os_aix_ppc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@

#define PLATFORM_PRINT_NATIVE_STACK 1
static bool platform_print_native_stack(outputStream* st, void* context,
char *buf, int buf_size);
char *buf, int buf_size, address& lastpc);

#define HAVE_FUNCTION_DESCRIPTORS 1
static void* resolve_function_descriptor(void* p);
Expand Down
9 changes: 5 additions & 4 deletions src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ bool os::register_code_area(char *low, char *high) {
* loop in vmError.cpp. We need to roll our own loop.
*/
bool os::platform_print_native_stack(outputStream* st, const void* context,
char *buf, int buf_size)
char *buf, int buf_size, address& lastpc)
{
CONTEXT ctx;
if (context != NULL) {
Expand All @@ -244,14 +244,14 @@ bool os::platform_print_native_stack(outputStream* st, const void* context,
stk.AddrPC.Mode = AddrModeFlat;

int count = 0;
address lastpc = 0;
address lastpc_internal = 0;
while (count++ < StackPrintLimit) {
intptr_t* sp = (intptr_t*)stk.AddrStack.Offset;
intptr_t* fp = (intptr_t*)stk.AddrFrame.Offset; // NOT necessarily the same as ctx.Rbp!
address pc = (address)stk.AddrPC.Offset;

if (pc != NULL) {
if (count == 2 && lastpc == pc) {
if (count == 2 && lastpc_internal == pc) {
// Skip it -- StackWalk64() may return the same PC
// (but different SP) on the first try.
} else {
Expand All @@ -267,12 +267,13 @@ bool os::platform_print_native_stack(outputStream* st, const void* context,
}
st->cr();
}
lastpc = pc;
lastpc_internal = pc;
}

PVOID p = WindowsDbgHelp::symFunctionTableAccess64(GetCurrentProcess(), stk.AddrPC.Offset);
if (!p) {
// StackWalk64() can't handle this PC. Calling StackWalk64 again may cause crash.
lastpc = lastpc_internal;
break;
}

Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/os_cpu/windows_x86/os_windows_x86.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
#ifdef AMD64
#define PLATFORM_PRINT_NATIVE_STACK 1
static bool platform_print_native_stack(outputStream* st, const void* context,
char *buf, int buf_size);
char *buf, int buf_size, address& lastpc);
#endif

#endif // OS_CPU_WINDOWS_X86_OS_WINDOWS_X86_HPP
2 changes: 1 addition & 1 deletion src/hotspot/share/runtime/os.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -886,7 +886,7 @@ class os: AllStatic {
#ifndef PLATFORM_PRINT_NATIVE_STACK
// No platform-specific code for printing the native stack.
static bool platform_print_native_stack(outputStream* st, const void* context,
char *buf, int buf_size) {
char *buf, int buf_size, address& lastpc) {
return false;
}
#endif
Expand Down
3 changes: 2 additions & 1 deletion src/hotspot/share/utilities/debug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -676,7 +676,8 @@ extern "C" JNIEXPORT void pns(void* sp, void* fp, void* pc) { // print native st
extern "C" JNIEXPORT void pns2() { // print native stack
Command c("pns2");
static char buf[O_BUFLEN];
if (os::platform_print_native_stack(tty, NULL, buf, sizeof(buf))) {
address lastpc = nullptr;
if (os::platform_print_native_stack(tty, NULL, buf, sizeof(buf), lastpc)) {
// We have printed the native stack in platform-specific code,
// so nothing else to do in this case.
} else {
Expand Down
41 changes: 40 additions & 1 deletion src/hotspot/share/utilities/vmError.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,27 @@ static bool print_code(outputStream* st, Thread* thread, address pc, bool is_cra
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`.
*
Expand Down Expand Up @@ -528,6 +549,10 @@ void VMError::report(outputStream* st, bool _verbose) {
// don't allocate large buffer on stack
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

STEP("printing fatal error message")
Expand Down Expand Up @@ -824,9 +849,16 @@ void VMError::report(outputStream* st, bool _verbose) {
STEP("printing native stack")

if (_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
// 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 {
frame fr = _context ? os::fetch_frame_from_context(_context)
: os::current_frame();
Expand Down Expand Up @@ -920,6 +952,13 @@ void VMError::report(outputStream* st, bool _verbose) {
// value outside the range.
int limit = MIN2(ErrorLogPrintCodeLimit, printed_capacity);
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
if (!_print_native_stack_used) {
// Only try to print code of the crashing frame since
Expand Down

1 comment on commit 8dae82c

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.