RFR: 8368787: Error reporting: hs_err files should show instructions when referencing code in nmethods [v4]
Thomas Stuefe
stuefe at openjdk.org
Thu Oct 23 09:01:14 UTC 2025
On Tue, 7 Oct 2025 17:45:38 GMT, Martin Doerr <mdoerr at openjdk.org> wrote:
>> We'd like to have a little more information in hs_err files in the following scenario: The VM crashes in code which does something with an nmethod. We often have a register pointing into code of the nmethod, but the nmethod is not disassembled in the hs_err file because the crash happens outside of it.
>>
>> We can disassemble some instructions around the address inside the nmethod code. This is tricky on platforms which have variable length instructions (like x86). We need to find correct instruction start addresses. I'm proposing to use relocations for this purpose. There are usually enough of them distributed over the nmethod and they point to instruction start addresses.
>>
>> I've tested this proposal by the following code on x86_64:
>>
>> diff --git a/src/hotspot/cpu/x86/interp_masm_x86.cpp b/src/hotspot/cpu/x86/interp_masm_x86.cpp
>> index a6b4efbe4f2..d715e69c850 100644
>> --- a/src/hotspot/cpu/x86/interp_masm_x86.cpp
>> +++ b/src/hotspot/cpu/x86/interp_masm_x86.cpp
>> @@ -646,6 +646,18 @@ void InterpreterMacroAssembler::prepare_to_jump_from_interpreted() {
>> void InterpreterMacroAssembler::jump_from_interpreted(Register method, Register temp) {
>> prepare_to_jump_from_interpreted();
>>
>> + if (UseNewCode) {
>> + Label ok;
>> + movptr(temp, Address(method, Method::from_interpreted_offset()));
>> + cmpptr(temp, Address(method, Method::interpreter_entry_offset()));
>> + je(ok);
>> + movptr(rax, Address(method, Method::from_compiled_offset()));
>> + movptr(rbx, rax);
>> + addptr(rbx, 128);
>> + hlt();
>> + bind(ok);
>> + }
>> +
>> if (JvmtiExport::can_post_interpreter_events()) {
>> Label run_compiled_code;
>> // JVMTI events, such as single-stepping, are implemented partly by avoiding running
>>
>>
>> The output is (requires hsdis library, otherwise we only get the hex dump):
>>
>> RAX=0x00007fa3e072c100 is at entry_point+0 in (nmethod*)0x00007fa3e072c008
>> Compiled method (c1) 2521 1 3 java.lang.Byte::toUnsignedInt (6 bytes)
>> total in heap [0x00007fa3e072c008,0x00007fa3e072c1f8] = 496
>> main code [0x00007fa3e072c100,0x00007fa3e072c1b8] = 184
>> stub code [0x00007fa3e072c1b8,0x00007fa3e072c1f8] = 64
>> mutable data [0x00007fa37c0160a0,0x00007fa37c0160d0] = 48
>> relocation [0x00007fa37c0160a0,0x00007fa37c0160c8] = 40
>> metadata [0x00007fa37c0160c8,0x00007fa37c0160d0] = 8
>> immutable data [0x00007fa37c015cc0,0x00007fa37c015d24] = 100
>> dependencies [0x00007fa37c015cc0,0x00007fa37c015...
>
> Martin Doerr has updated the pull request incrementally with one additional commit since the last revision:
>
> Use frame_complete_offset for better start address computation. Improve comments.
src/hotspot/share/code/nmethod.cpp line 4026:
> 4024: if (iter.has_current()) end = iter.addr();
> 4025: }
> 4026:
IIUC, the size of the printout is somewhat random. In the extreme cases, this may be either (close to) start-of-method to end-of-method, so almost the whole method. Or, it may be from an address very close to the address, so a very small snippet.
Tying the end address to a relocation is not strictly necessary, no? We could just print to `MIN2(code end, addr + 64)? Disassembler should be fine if the printout stops in the middle of an instruction, as long as instruction addresses are correct?
And could we start printing at the relocation preceding-or-at `addr - 64` instead, to ensure we have at least 64 bytes of printout before the crash address?
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/27530#discussion_r2454415847
More information about the hotspot-compiler-dev
mailing list