8368787: Error reporting: hs_err files should show instructions when referencing code in nmethods

Reviewed-by: stuefe, aph, mbaesken, shade
This commit is contained in:
Martin Doerr 2025-10-24 08:26:24 +00:00
parent 26eed3b61e
commit b31bbfcf2f
3 changed files with 42 additions and 0 deletions

View File

@ -910,6 +910,7 @@ void CodeBlob::dump_for_addr(address addr, outputStream* st, bool verbose) const
nm->print_nmethod(true);
} else {
nm->print_on(st);
nm->print_code_snippet(st, addr);
}
return;
}

View File

@ -4308,6 +4308,46 @@ void nmethod::print_value_on_impl(outputStream* st) const {
#endif
}
void nmethod::print_code_snippet(outputStream* st, address addr) const {
if (entry_point() <= addr && addr < code_end()) {
// Pointing into the nmethod's code. Try to disassemble some instructions around addr.
// Determine conservative start and end points.
address start;
if (frame_complete_offset() != CodeOffsets::frame_never_safe &&
addr >= code_begin() + frame_complete_offset()) {
start = code_begin() + frame_complete_offset();
} else {
start = (addr < verified_entry_point()) ? entry_point() : verified_entry_point();
}
address start_for_hex_dump = start; // We can choose a different starting point for hex dump, below.
address end = code_end();
// Try using relocations to find closer instruction start and end points.
// (Some platforms have variable length instructions and can only
// disassemble correctly at instruction start addresses.)
RelocIterator iter((nmethod*)this, start);
while (iter.next() && iter.addr() < addr) { // find relocation before addr
// Note: There's a relocation which doesn't point to an instruction start:
// ZBarrierRelocationFormatStoreGoodAfterMov with ZGC on x86_64
// We could detect and skip it, but hex dump is still usable when
// disassembler produces garbage in such a very rare case.
start = iter.addr();
// We want at least 64 Bytes ahead in hex dump.
if (iter.addr() <= (addr - 64)) start_for_hex_dump = iter.addr();
}
if (iter.has_current()) {
if (iter.addr() == addr) iter.next(); // find relocation after addr
if (iter.has_current()) end = iter.addr();
}
// Always print hex. Disassembler may still have problems when hitting an incorrect instruction start.
os::print_hex_dump(st, start_for_hex_dump, end, 1, /* print_ascii=*/false);
if (!Disassembler::is_abstract()) {
Disassembler::decode(start, end, st);
}
}
}
#ifndef PRODUCT
void nmethod::print_calls(outputStream* st) {

View File

@ -1008,6 +1008,7 @@ public:
void print_on_impl(outputStream* st) const;
void print_code();
void print_value_on_impl(outputStream* st) const;
void print_code_snippet(outputStream* st, address addr) const;
#if defined(SUPPORT_DATA_STRUCTS)
// print output in opt build for disassembler library