On Fri, 9 Oct 2026 06:21:15 GMT, Justus Garbe <[email protected]> wrote:

>> A rare bug with the jdk has recently been filed again: 
>> https://github.com/adoptium/adoptium-support/issues/1538, which reports the 
>> already seen behavior in JDK-8352077: `unhandled instruction`. The original 
>> issue was closed with no reproduction. I have managed to write a 
>> reproduction with the new data.
>> 
>> It seems that it is caused by a missing null check in the 
>> `BreakpointInfo::set` path, which calls into:
>> `incr_number_of_breakpoints` which calls `build_method_counters`. Which has 
>> multiple ways to return `nullptr` if either the oom flag is already set or 
>> the allocation fails, which is done via allocate_no_exception since it runs 
>> on a VMThread, therefore it cant actually call a GC or raise the metadata 
>> limit. Therefore incr_number_of_breakpoints, never increases the number 
>> (since method counters is nullptr). Compilation is then paused, because the 
>> method cannot increase it's invocation counter, then after a purge caused by 
>> a gc pass, the mark is unset. After that it can correctly create it's 
>> counter, but since it never captured the breakpoints, the breakpoint is 0.
>> 
>> The method then can be picked up by a compiler thread since 
>> `number_of_breakpoints` is now 0 and a counter is real it falsely passes 
>> `Method::is_not_compilable`. Then it copies the bytecode containing the 
>> `breakpoint` instruction, and doesn't invoke the clean function since the 
>> breakpoint count reports '0'. This causes a crash in the `ciBytecodeStream` 
>> since `ciBytecodeStream::next_wide_or_table` assumes the only special 
>> bytecodes can be `wide` or a type of switch, and bytecode is a special 
>> length instruction. 
>> 
>> This also explains why this happens so rarely. For this to happen the 
>> following need to happen in succession:
>> - The debugger must try to set breakpoints
>> - The method must never have been run
>> - Metadata space needs to be at the limit and not resized when its setting 
>> the breakpoints and set the oom flag
>> - Class unloading must purge the flag afterwards
>> - The method must get compiled hot while the breakpoint is still installed 
>> 
>> 3 of the 5 conditions already happen when debugging with jdwp normally, from 
>> platforms like intellij, the others are race / resource conditions that seem 
>> happen very rarely.
>> 
>> For the fix i propose to check the method counter allocation before actually 
>> requesting a breakpoint set. Here done by checking if method counters are 
>> not null before sending the vm request. I also had to expand the user facing 
>> method to make sure the OOM error c...
>
> Justus Garbe has updated the pull request incrementally with two additional 
> commits since the last revision:
> 
>  - Add explicit timeout
>  - Use atomic for hits

Changes requested by lmesnik (Reviewer).

test/hotspot/jtreg/serviceability/jvmti/SetBreakpoint/BreakpointMetaspaceOOM.java
 line 32:

> 30:  * @build jdk.test.whitebox.WhiteBox
> 31:  * @run driver jdk.test.lib.helpers.ClassFileInstaller 
> jdk.test.whitebox.WhiteBox
> 32:  * @run main/othervm/native/timeout=240

It is quite expensive test for rare edge case. Please ensure that it is 
excluded from tier1.

-------------

PR Review: https://git.openjdk.org/jdk/pull/33191#pullrequestreview-5477452105
PR Review Comment: https://git.openjdk.org/jdk/pull/33191#discussion_r4236297509

Reply via email to