8343343: Misc crash dump improvements on more platforms after JDK-8294160
Co-authored-by: Boris Ulasevich <bulasevich@openjdk.org> Reviewed-by: mbaesken, jkern, dlong
This commit is contained in:
parent
d20ccd1aef
commit
e33dc13567
@ -123,13 +123,13 @@ frame os::fetch_frame_from_context(const void* ucVoid) {
|
||||
intptr_t* sp;
|
||||
intptr_t* fp;
|
||||
address epc = fetch_frame_from_context(ucVoid, &sp, &fp);
|
||||
// Avoid crash during crash if pc broken.
|
||||
if (epc) {
|
||||
frame fr(sp, epc, frame::kind::unknown);
|
||||
return fr;
|
||||
if (epc == nullptr || !is_readable_pointer(epc)) {
|
||||
// Try to recover from calling into bad memory
|
||||
// Assume new frame has not been set up, the same as
|
||||
// compiled frame stack bang
|
||||
return fetch_compiled_frame_from_context(ucVoid);
|
||||
}
|
||||
frame fr(sp);
|
||||
return fr;
|
||||
return frame(sp, epc, frame::kind::unknown);
|
||||
}
|
||||
|
||||
frame os::fetch_compiled_frame_from_context(const void* ucVoid) {
|
||||
@ -447,23 +447,6 @@ void os::print_context(outputStream *st, const void *context) {
|
||||
st->cr();
|
||||
}
|
||||
|
||||
void os::print_tos_pc(outputStream *st, const void *context) {
|
||||
if (context == nullptr) return;
|
||||
|
||||
const ucontext_t* uc = (const ucontext_t*)context;
|
||||
|
||||
address sp = (address)os::Aix::ucontext_get_sp(uc);
|
||||
print_tos(st, sp);
|
||||
st->cr();
|
||||
|
||||
// Note: it may be unsafe to inspect memory near pc. For example, pc may
|
||||
// point to garbage if entry point in an nmethod is corrupted. Leave
|
||||
// this at the end, and hope for the best.
|
||||
address pc = os::Posix::ucontext_get_pc(uc);
|
||||
print_instructions(st, pc);
|
||||
st->cr();
|
||||
}
|
||||
|
||||
void os::print_register_info(outputStream *st, const void *context, int& continuation) {
|
||||
const int register_count = 32 /* r0-r32 */ + 3 /* pc, lr, sp */;
|
||||
int n = continuation;
|
||||
|
@ -159,6 +159,12 @@ frame os::fetch_frame_from_context(const void* ucVoid) {
|
||||
intptr_t* sp;
|
||||
intptr_t* fp;
|
||||
address epc = fetch_frame_from_context(ucVoid, &sp, &fp);
|
||||
if (!is_readable_pointer(epc)) {
|
||||
// Try to recover from calling into bad memory
|
||||
// Assume new frame has not been set up, the same as
|
||||
// compiled frame stack bang
|
||||
return fetch_compiled_frame_from_context(ucVoid);
|
||||
}
|
||||
return frame(sp, fp, epc);
|
||||
}
|
||||
|
||||
@ -442,23 +448,6 @@ void os::print_context(outputStream *st, const void *context) {
|
||||
st->cr();
|
||||
}
|
||||
|
||||
void os::print_tos_pc(outputStream *st, const void *context) {
|
||||
if (context == nullptr) return;
|
||||
|
||||
const ucontext_t* uc = (const ucontext_t*)context;
|
||||
|
||||
address sp = (address)os::Bsd::ucontext_get_sp(uc);
|
||||
print_tos(st, sp);
|
||||
st->cr();
|
||||
|
||||
// Note: it may be unsafe to inspect memory near pc. For example, pc may
|
||||
// point to garbage if entry point in an nmethod is corrupted. Leave
|
||||
// this at the end, and hope for the best.
|
||||
address pc = os::Posix::ucontext_get_pc(uc);
|
||||
print_instructions(st, pc);
|
||||
st->cr();
|
||||
}
|
||||
|
||||
void os::print_register_info(outputStream *st, const void *context, int& continuation) {
|
||||
const int register_count = 29 /* x0-x28 */ + 3 /* fp, lr, sp */;
|
||||
int n = continuation;
|
||||
|
@ -333,6 +333,12 @@ frame os::fetch_frame_from_context(const void* ucVoid) {
|
||||
intptr_t* sp;
|
||||
intptr_t* fp;
|
||||
address epc = fetch_frame_from_context(ucVoid, &sp, &fp);
|
||||
if (!is_readable_pointer(epc)) {
|
||||
// Try to recover from calling into bad memory
|
||||
// Assume new frame has not been set up, the same as
|
||||
// compiled frame stack bang
|
||||
return fetch_compiled_frame_from_context(ucVoid);
|
||||
}
|
||||
return frame(sp, fp, epc);
|
||||
}
|
||||
|
||||
@ -836,23 +842,6 @@ void os::print_context(outputStream *st, const void *context) {
|
||||
st->cr();
|
||||
}
|
||||
|
||||
void os::print_tos_pc(outputStream *st, const void *context) {
|
||||
if (context == nullptr) return;
|
||||
|
||||
const ucontext_t* uc = (const ucontext_t*)context;
|
||||
|
||||
address sp = (address)os::Bsd::ucontext_get_sp(uc);
|
||||
print_tos(st, sp);
|
||||
st->cr();
|
||||
|
||||
// Note: it may be unsafe to inspect memory near pc. For example, pc may
|
||||
// point to garbage if entry point in an nmethod is corrupted. Leave
|
||||
// this at the end, and hope for the best.
|
||||
address pc = os::Posix::ucontext_get_pc(uc);
|
||||
print_instructions(st, pc);
|
||||
st->cr();
|
||||
}
|
||||
|
||||
void os::print_register_info(outputStream *st, const void *context, int& continuation) {
|
||||
const int register_count = AMD64_ONLY(16) NOT_AMD64(8);
|
||||
int n = continuation;
|
||||
|
@ -228,10 +228,6 @@ void os::print_context(outputStream* st, const void* context) {
|
||||
ShouldNotCallThis();
|
||||
}
|
||||
|
||||
void os::print_tos_pc(outputStream *st, const void *context) {
|
||||
ShouldNotCallThis();
|
||||
}
|
||||
|
||||
void os::print_register_info(outputStream *st, const void *context, int& continuation) {
|
||||
ShouldNotCallThis();
|
||||
}
|
||||
|
@ -354,23 +354,6 @@ void os::print_context(outputStream *st, const void *context) {
|
||||
st->cr();
|
||||
}
|
||||
|
||||
void os::print_tos_pc(outputStream *st, const void *context) {
|
||||
if (context == nullptr) return;
|
||||
|
||||
const ucontext_t* uc = (const ucontext_t*)context;
|
||||
|
||||
address sp = (address)os::Linux::ucontext_get_sp(uc);
|
||||
print_tos(st, sp);
|
||||
st->cr();
|
||||
|
||||
// Note: it may be unsafe to inspect memory near pc. For example, pc may
|
||||
// point to garbage if entry point in an nmethod is corrupted. Leave
|
||||
// this at the end, and hope for the best.
|
||||
address pc = os::fetch_frame_from_context(uc).pc();
|
||||
print_instructions(st, pc);
|
||||
st->cr();
|
||||
}
|
||||
|
||||
void os::print_register_info(outputStream *st, const void *context, int& continuation) {
|
||||
const int register_count = 32 /* r0-r31 */;
|
||||
int n = continuation;
|
||||
|
@ -188,9 +188,27 @@ frame os::fetch_frame_from_context(const void* ucVoid) {
|
||||
intptr_t* sp;
|
||||
intptr_t* fp;
|
||||
address epc = fetch_frame_from_context(ucVoid, &sp, &fp);
|
||||
if (!is_readable_pointer(epc)) {
|
||||
// Try to recover from calling into bad memory
|
||||
// Assume new frame has not been set up, the same as
|
||||
// compiled frame stack bang
|
||||
return fetch_compiled_frame_from_context(ucVoid);
|
||||
}
|
||||
return frame(sp, fp, epc);
|
||||
}
|
||||
|
||||
frame os::fetch_compiled_frame_from_context(const void* ucVoid) {
|
||||
const ucontext_t* uc = (const ucontext_t*)ucVoid;
|
||||
// In compiled code, the stack banging is performed before LR
|
||||
// has been saved in the frame. LR is live, and SP and FP
|
||||
// belong to the caller.
|
||||
intptr_t* fp = os::Linux::ucontext_get_fp(uc);
|
||||
intptr_t* sp = os::Linux::ucontext_get_sp(uc);
|
||||
address pc = (address)(uc->uc_mcontext.arm_lr
|
||||
- NativeInstruction::instruction_size);
|
||||
return frame(sp, fp, pc);
|
||||
}
|
||||
|
||||
frame os::get_sender_for_C_frame(frame* fr) {
|
||||
#ifdef __thumb__
|
||||
// We can't reliably get anything from a thumb C frame.
|
||||
@ -474,23 +492,6 @@ void os::print_context(outputStream *st, const void *context) {
|
||||
st->cr();
|
||||
}
|
||||
|
||||
void os::print_tos_pc(outputStream *st, const void *context) {
|
||||
if (context == nullptr) return;
|
||||
|
||||
const ucontext_t* uc = (const ucontext_t*)context;
|
||||
|
||||
address sp = (address)os::Linux::ucontext_get_sp(uc);
|
||||
print_tos(st, sp);
|
||||
st->cr();
|
||||
|
||||
// Note: it may be unsafe to inspect memory near pc. For example, pc may
|
||||
// point to garbage if entry point in an nmethod is corrupted. Leave
|
||||
// this at the end, and hope for the best.
|
||||
address pc = os::Posix::ucontext_get_pc(uc);
|
||||
print_instructions(st, pc);
|
||||
st->cr();
|
||||
}
|
||||
|
||||
void os::print_register_info(outputStream *st, const void *context, int& continuation) {
|
||||
const int register_count = ARM_REGS_IN_CONTEXT;
|
||||
int n = continuation;
|
||||
|
@ -155,6 +155,12 @@ frame os::fetch_frame_from_context(const void* ucVoid) {
|
||||
intptr_t* sp;
|
||||
intptr_t* fp;
|
||||
address epc = fetch_frame_from_context(ucVoid, &sp, &fp);
|
||||
if (!is_readable_pointer(epc)) {
|
||||
// Try to recover from calling into bad memory
|
||||
// Assume new frame has not been set up, the same as
|
||||
// compiled frame stack bang
|
||||
return fetch_compiled_frame_from_context(ucVoid);
|
||||
}
|
||||
return frame(sp, epc, frame::kind::unknown);
|
||||
}
|
||||
|
||||
@ -461,23 +467,6 @@ void os::print_context(outputStream *st, const void *context) {
|
||||
st->cr();
|
||||
}
|
||||
|
||||
void os::print_tos_pc(outputStream *st, const void *context) {
|
||||
if (context == nullptr) return;
|
||||
|
||||
const ucontext_t* uc = (const ucontext_t*)context;
|
||||
|
||||
address sp = (address)os::Linux::ucontext_get_sp(uc);
|
||||
print_tos(st, sp);
|
||||
st->cr();
|
||||
|
||||
// Note: it may be unsafe to inspect memory near pc. For example, pc may
|
||||
// point to garbage if entry point in an nmethod is corrupted. Leave
|
||||
// this at the end, and hope for the best.
|
||||
address pc = os::Posix::ucontext_get_pc(uc);
|
||||
print_instructions(st, pc);
|
||||
st->cr();
|
||||
}
|
||||
|
||||
void os::print_register_info(outputStream *st, const void *context, int& continuation) {
|
||||
const int register_count = 32 /* r0-r32 */ + 3 /* pc, lr, ctr */;
|
||||
int n = continuation;
|
||||
|
@ -352,23 +352,6 @@ void os::print_context(outputStream *st, const void *context) {
|
||||
st->cr();
|
||||
}
|
||||
|
||||
void os::print_tos_pc(outputStream *st, const void *context) {
|
||||
if (context == nullptr) return;
|
||||
|
||||
const ucontext_t* uc = (const ucontext_t*)context;
|
||||
|
||||
address sp = (address)os::Linux::ucontext_get_sp(uc);
|
||||
print_tos(st, sp);
|
||||
st->cr();
|
||||
|
||||
// Note: it may be unsafe to inspect memory near pc. For example, pc may
|
||||
// point to garbage if entry point in an nmethod is corrupted. Leave
|
||||
// this at the end, and hope for the best.
|
||||
address pc = os::fetch_frame_from_context(uc).pc();
|
||||
print_instructions(st, pc);
|
||||
st->cr();
|
||||
}
|
||||
|
||||
void os::print_register_info(outputStream *st, const void *context, int& continuation) {
|
||||
const int register_count = 32;
|
||||
int n = continuation;
|
||||
|
@ -140,6 +140,12 @@ frame os::fetch_frame_from_context(const void* ucVoid) {
|
||||
intptr_t* sp;
|
||||
intptr_t* fp;
|
||||
address epc = fetch_frame_from_context(ucVoid, &sp, &fp);
|
||||
if (!is_readable_pointer(epc)) {
|
||||
// Try to recover from calling into bad memory
|
||||
// Assume new frame has not been set up, the same as
|
||||
// compiled frame stack bang
|
||||
return fetch_compiled_frame_from_context(ucVoid);
|
||||
}
|
||||
return frame(sp, epc);
|
||||
}
|
||||
|
||||
@ -442,23 +448,6 @@ void os::print_context(outputStream *st, const void *context) {
|
||||
st->cr();
|
||||
}
|
||||
|
||||
void os::print_tos_pc(outputStream *st, const void *context) {
|
||||
if (context == nullptr) return;
|
||||
|
||||
const ucontext_t* uc = (const ucontext_t*)context;
|
||||
|
||||
address sp = (address)os::Linux::ucontext_get_sp(uc);
|
||||
print_tos(st, sp);
|
||||
st->cr();
|
||||
|
||||
// Note: it may be unsafe to inspect memory near pc. For example, pc may
|
||||
// point to garbage if entry point in an nmethod is corrupted. Leave
|
||||
// this at the end, and hope for the best.
|
||||
address pc = os::Posix::ucontext_get_pc(uc);
|
||||
print_instructions(st, pc);
|
||||
st->cr();
|
||||
}
|
||||
|
||||
void os::print_register_info(outputStream *st, const void *context, int& continuation) {
|
||||
const int register_count = 16 /* r0-r15 */ + 1 /* pc */;
|
||||
int n = continuation;
|
||||
|
@ -578,23 +578,6 @@ void os::print_context(outputStream *st, const void *context) {
|
||||
st->cr();
|
||||
}
|
||||
|
||||
void os::print_tos_pc(outputStream *st, const void *context) {
|
||||
if (context == nullptr) return;
|
||||
|
||||
const ucontext_t* uc = (const ucontext_t*)context;
|
||||
|
||||
address sp = (address)os::Linux::ucontext_get_sp(uc);
|
||||
print_tos(st, sp);
|
||||
st->cr();
|
||||
|
||||
// Note: it may be unsafe to inspect memory near pc. For example, pc may
|
||||
// point to garbage if entry point in an nmethod is corrupted. Leave
|
||||
// this at the end, and hope for the best.
|
||||
address pc = os::fetch_frame_from_context(uc).pc();
|
||||
print_instructions(st, pc);
|
||||
st->cr();
|
||||
}
|
||||
|
||||
void os::print_register_info(outputStream *st, const void *context, int& continuation) {
|
||||
const int register_count = AMD64_ONLY(16) NOT_AMD64(8);
|
||||
int n = continuation;
|
||||
|
@ -376,21 +376,6 @@ void os::print_context(outputStream* st, const void* ucVoid) {
|
||||
st->print_cr("No context information.");
|
||||
}
|
||||
|
||||
void os::print_tos_pc(outputStream *st, const void* ucVoid) {
|
||||
const ucontext_t* uc = (const ucontext_t*)ucVoid;
|
||||
|
||||
address sp = (address)os::Linux::ucontext_get_sp(uc);
|
||||
print_tos(st, sp);
|
||||
st->cr();
|
||||
|
||||
// Note: it may be unsafe to inspect memory near pc. For example, pc may
|
||||
// point to garbage if entry point in an nmethod is corrupted. Leave
|
||||
// this at the end, and hope for the best.
|
||||
address pc = os::Posix::ucontext_get_pc(uc);
|
||||
print_instructions(st, pc);
|
||||
st->cr();
|
||||
}
|
||||
|
||||
void os::print_register_info(outputStream *st, const void *context, int& continuation) {
|
||||
st->print_cr("No register info.");
|
||||
}
|
||||
|
@ -205,24 +205,6 @@ void os::print_context(outputStream *st, const void *context) {
|
||||
st->cr();
|
||||
}
|
||||
|
||||
void os::print_tos_pc(outputStream *st, const void *context) {
|
||||
if (context == nullptr) return;
|
||||
|
||||
const CONTEXT* uc = (const CONTEXT*)context;
|
||||
|
||||
address sp = (address)uc->Sp;
|
||||
print_tos(st, sp);
|
||||
st->cr();
|
||||
|
||||
// Note: it may be unsafe to inspect memory near pc. For example, pc may
|
||||
// point to garbage if entry point in an nmethod is corrupted. Leave
|
||||
// this at the end, and hope for the best.
|
||||
address pc = (address)uc->Pc;
|
||||
st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc);
|
||||
print_hex_dump(st, pc - 32, pc + 32, sizeof(char), /* print_ascii=*/false);
|
||||
st->cr();
|
||||
}
|
||||
|
||||
void os::print_register_info(outputStream *st, const void *context, int& continuation) {
|
||||
const int register_count = 29 /* X0-X28 */;
|
||||
int n = continuation;
|
||||
|
@ -464,23 +464,6 @@ void os::print_context(outputStream *st, const void *context) {
|
||||
st->cr();
|
||||
}
|
||||
|
||||
void os::print_tos_pc(outputStream *st, const void *context) {
|
||||
if (context == nullptr) return;
|
||||
|
||||
const CONTEXT* uc = (const CONTEXT*)context;
|
||||
|
||||
address sp = (address)uc->REG_SP;
|
||||
print_tos(st, sp);
|
||||
st->cr();
|
||||
|
||||
// Note: it may be unsafe to inspect memory near pc. For example, pc may
|
||||
// point to garbage if entry point in an nmethod is corrupted. Leave
|
||||
// this at the end, and hope for the best.
|
||||
address pc = os::fetch_frame_from_context(uc).pc();
|
||||
print_instructions(st, pc);
|
||||
st->cr();
|
||||
}
|
||||
|
||||
void os::print_register_info(outputStream *st, const void *context, int& continuation) {
|
||||
const int register_count = AMD64_ONLY(16) NOT_AMD64(8);
|
||||
int n = continuation;
|
||||
|
@ -1083,6 +1083,26 @@ void os::print_dhm(outputStream* st, const char* startStr, long sec) {
|
||||
st->print_cr("%s %ld days %ld:%02ld hours", startStr, days, hours, minutes);
|
||||
}
|
||||
|
||||
void os::print_tos_pc(outputStream* st, const void* context) {
|
||||
if (context == nullptr) return;
|
||||
|
||||
// First of all, carefully determine sp without inspecting memory near pc.
|
||||
// See comment below.
|
||||
intptr_t* sp = nullptr;
|
||||
fetch_frame_from_context(context, &sp, nullptr);
|
||||
print_tos(st, (address)sp);
|
||||
st->cr();
|
||||
|
||||
// Note: it may be unsafe to inspect memory near pc. For example, pc may
|
||||
// point to garbage if entry point in an nmethod is corrupted. Leave
|
||||
// this at the end, and hope for the best.
|
||||
// This version of fetch_frame_from_context finds the caller pc if the actual
|
||||
// one is bad.
|
||||
address pc = fetch_frame_from_context(context).pc();
|
||||
print_instructions(st, pc);
|
||||
st->cr();
|
||||
}
|
||||
|
||||
void os::print_tos(outputStream* st, address sp) {
|
||||
st->print_cr("Top of Stack: (sp=" PTR_FORMAT ")", p2i(sp));
|
||||
print_hex_dump(st, sp, sp + 512, sizeof(intptr_t));
|
||||
|
Loading…
Reference in New Issue
Block a user