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* sp;
|
||||||
intptr_t* fp;
|
intptr_t* fp;
|
||||||
address epc = fetch_frame_from_context(ucVoid, &sp, &fp);
|
address epc = fetch_frame_from_context(ucVoid, &sp, &fp);
|
||||||
// Avoid crash during crash if pc broken.
|
if (epc == nullptr || !is_readable_pointer(epc)) {
|
||||||
if (epc) {
|
// Try to recover from calling into bad memory
|
||||||
frame fr(sp, epc, frame::kind::unknown);
|
// Assume new frame has not been set up, the same as
|
||||||
return fr;
|
// compiled frame stack bang
|
||||||
|
return fetch_compiled_frame_from_context(ucVoid);
|
||||||
}
|
}
|
||||||
frame fr(sp);
|
return frame(sp, epc, frame::kind::unknown);
|
||||||
return fr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
frame os::fetch_compiled_frame_from_context(const void* ucVoid) {
|
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();
|
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) {
|
void os::print_register_info(outputStream *st, const void *context, int& continuation) {
|
||||||
const int register_count = 32 /* r0-r32 */ + 3 /* pc, lr, sp */;
|
const int register_count = 32 /* r0-r32 */ + 3 /* pc, lr, sp */;
|
||||||
int n = continuation;
|
int n = continuation;
|
||||||
|
@ -159,6 +159,12 @@ frame os::fetch_frame_from_context(const void* ucVoid) {
|
|||||||
intptr_t* sp;
|
intptr_t* sp;
|
||||||
intptr_t* fp;
|
intptr_t* fp;
|
||||||
address epc = fetch_frame_from_context(ucVoid, &sp, &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);
|
return frame(sp, fp, epc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -442,23 +448,6 @@ void os::print_context(outputStream *st, const void *context) {
|
|||||||
st->cr();
|
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) {
|
void os::print_register_info(outputStream *st, const void *context, int& continuation) {
|
||||||
const int register_count = 29 /* x0-x28 */ + 3 /* fp, lr, sp */;
|
const int register_count = 29 /* x0-x28 */ + 3 /* fp, lr, sp */;
|
||||||
int n = continuation;
|
int n = continuation;
|
||||||
|
@ -333,6 +333,12 @@ frame os::fetch_frame_from_context(const void* ucVoid) {
|
|||||||
intptr_t* sp;
|
intptr_t* sp;
|
||||||
intptr_t* fp;
|
intptr_t* fp;
|
||||||
address epc = fetch_frame_from_context(ucVoid, &sp, &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);
|
return frame(sp, fp, epc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -836,23 +842,6 @@ void os::print_context(outputStream *st, const void *context) {
|
|||||||
st->cr();
|
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) {
|
void os::print_register_info(outputStream *st, const void *context, int& continuation) {
|
||||||
const int register_count = AMD64_ONLY(16) NOT_AMD64(8);
|
const int register_count = AMD64_ONLY(16) NOT_AMD64(8);
|
||||||
int n = continuation;
|
int n = continuation;
|
||||||
|
@ -228,10 +228,6 @@ void os::print_context(outputStream* st, const void* context) {
|
|||||||
ShouldNotCallThis();
|
ShouldNotCallThis();
|
||||||
}
|
}
|
||||||
|
|
||||||
void os::print_tos_pc(outputStream *st, const void *context) {
|
|
||||||
ShouldNotCallThis();
|
|
||||||
}
|
|
||||||
|
|
||||||
void os::print_register_info(outputStream *st, const void *context, int& continuation) {
|
void os::print_register_info(outputStream *st, const void *context, int& continuation) {
|
||||||
ShouldNotCallThis();
|
ShouldNotCallThis();
|
||||||
}
|
}
|
||||||
|
@ -354,23 +354,6 @@ void os::print_context(outputStream *st, const void *context) {
|
|||||||
st->cr();
|
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) {
|
void os::print_register_info(outputStream *st, const void *context, int& continuation) {
|
||||||
const int register_count = 32 /* r0-r31 */;
|
const int register_count = 32 /* r0-r31 */;
|
||||||
int n = continuation;
|
int n = continuation;
|
||||||
|
@ -188,9 +188,27 @@ frame os::fetch_frame_from_context(const void* ucVoid) {
|
|||||||
intptr_t* sp;
|
intptr_t* sp;
|
||||||
intptr_t* fp;
|
intptr_t* fp;
|
||||||
address epc = fetch_frame_from_context(ucVoid, &sp, &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);
|
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) {
|
frame os::get_sender_for_C_frame(frame* fr) {
|
||||||
#ifdef __thumb__
|
#ifdef __thumb__
|
||||||
// We can't reliably get anything from a thumb C frame.
|
// 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();
|
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) {
|
void os::print_register_info(outputStream *st, const void *context, int& continuation) {
|
||||||
const int register_count = ARM_REGS_IN_CONTEXT;
|
const int register_count = ARM_REGS_IN_CONTEXT;
|
||||||
int n = continuation;
|
int n = continuation;
|
||||||
|
@ -155,6 +155,12 @@ frame os::fetch_frame_from_context(const void* ucVoid) {
|
|||||||
intptr_t* sp;
|
intptr_t* sp;
|
||||||
intptr_t* fp;
|
intptr_t* fp;
|
||||||
address epc = fetch_frame_from_context(ucVoid, &sp, &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);
|
return frame(sp, epc, frame::kind::unknown);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,23 +467,6 @@ void os::print_context(outputStream *st, const void *context) {
|
|||||||
st->cr();
|
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) {
|
void os::print_register_info(outputStream *st, const void *context, int& continuation) {
|
||||||
const int register_count = 32 /* r0-r32 */ + 3 /* pc, lr, ctr */;
|
const int register_count = 32 /* r0-r32 */ + 3 /* pc, lr, ctr */;
|
||||||
int n = continuation;
|
int n = continuation;
|
||||||
|
@ -352,23 +352,6 @@ void os::print_context(outputStream *st, const void *context) {
|
|||||||
st->cr();
|
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) {
|
void os::print_register_info(outputStream *st, const void *context, int& continuation) {
|
||||||
const int register_count = 32;
|
const int register_count = 32;
|
||||||
int n = continuation;
|
int n = continuation;
|
||||||
|
@ -140,6 +140,12 @@ frame os::fetch_frame_from_context(const void* ucVoid) {
|
|||||||
intptr_t* sp;
|
intptr_t* sp;
|
||||||
intptr_t* fp;
|
intptr_t* fp;
|
||||||
address epc = fetch_frame_from_context(ucVoid, &sp, &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);
|
return frame(sp, epc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -442,23 +448,6 @@ void os::print_context(outputStream *st, const void *context) {
|
|||||||
st->cr();
|
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) {
|
void os::print_register_info(outputStream *st, const void *context, int& continuation) {
|
||||||
const int register_count = 16 /* r0-r15 */ + 1 /* pc */;
|
const int register_count = 16 /* r0-r15 */ + 1 /* pc */;
|
||||||
int n = continuation;
|
int n = continuation;
|
||||||
|
@ -578,23 +578,6 @@ void os::print_context(outputStream *st, const void *context) {
|
|||||||
st->cr();
|
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) {
|
void os::print_register_info(outputStream *st, const void *context, int& continuation) {
|
||||||
const int register_count = AMD64_ONLY(16) NOT_AMD64(8);
|
const int register_count = AMD64_ONLY(16) NOT_AMD64(8);
|
||||||
int n = continuation;
|
int n = continuation;
|
||||||
|
@ -376,21 +376,6 @@ void os::print_context(outputStream* st, const void* ucVoid) {
|
|||||||
st->print_cr("No context information.");
|
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) {
|
void os::print_register_info(outputStream *st, const void *context, int& continuation) {
|
||||||
st->print_cr("No register info.");
|
st->print_cr("No register info.");
|
||||||
}
|
}
|
||||||
|
@ -205,24 +205,6 @@ void os::print_context(outputStream *st, const void *context) {
|
|||||||
st->cr();
|
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) {
|
void os::print_register_info(outputStream *st, const void *context, int& continuation) {
|
||||||
const int register_count = 29 /* X0-X28 */;
|
const int register_count = 29 /* X0-X28 */;
|
||||||
int n = continuation;
|
int n = continuation;
|
||||||
|
@ -464,23 +464,6 @@ void os::print_context(outputStream *st, const void *context) {
|
|||||||
st->cr();
|
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) {
|
void os::print_register_info(outputStream *st, const void *context, int& continuation) {
|
||||||
const int register_count = AMD64_ONLY(16) NOT_AMD64(8);
|
const int register_count = AMD64_ONLY(16) NOT_AMD64(8);
|
||||||
int n = continuation;
|
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);
|
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) {
|
void os::print_tos(outputStream* st, address sp) {
|
||||||
st->print_cr("Top of Stack: (sp=" PTR_FORMAT ")", p2i(sp));
|
st->print_cr("Top of Stack: (sp=" PTR_FORMAT ")", p2i(sp));
|
||||||
print_hex_dump(st, sp, sp + 512, sizeof(intptr_t));
|
print_hex_dump(st, sp, sp + 512, sizeof(intptr_t));
|
||||||
|
Loading…
Reference in New Issue
Block a user