Question about jmethodId and class unloading
Thomas Stüfe
thomas.stuefe at gmail.com
Fri Apr 15 08:43:34 UTC 2022
Thank you David, that makes sense.
>From the answers I take that my technical assumption is correct: there is
no graceful way to prevent crashes or ending up with the wrong Method* if
you misuse jmethodid. And that its the responsibility of the JNI programmer
to make sure the jmethodid is valid. So he has to know about class
unloading and, wrt AGCT, make sure you don't use the method ids beyond the
frame that called AGCT. async-profiler in particular should resolve the
method id right away in their SIGPROF handler (I suppose they do; Idk. I
have not looked at the sources yet).
Cheers, Thomas
On Thu, Apr 14, 2022 at 9:55 AM David Holmes <david.holmes at oracle.com>
wrote:
> On 14/04/2022 12:25 am, Thomas Stüfe wrote:
> > Thank you, Volker.
> >
> > I was actually concerned about AsyncGetCallTrace, which seems to return
> > just an array of jmethodIds as stack. These could become invalid the
> moment
> > they are handed out.
>
> They would still be valid when the call to AGCT returns as the methods
> are still on the stack. Now if the caller of AGCT simply stashes away
> those jmethodIds for later use by some other piece of code, then yes
> that is a problem. But that is the problem of the user of AGCT not AGCT
> itself - no?
>
> Cheers,
> David
>
> > Cheers, Thomas
> >
> > On Wed, Apr 13, 2022 at 2:51 PM Volker Simonis <volker.simonis at gmail.com
> >
> > wrote:
> >
> >> For an instance method you need an instance of that class anyway if you
> >> want to call the method, so the class can't be unloaded.
> >>
> >> But in general you're right, JNI gives you no guarantees at all. It even
> >> explicitly warns about this situation. See:
> >>
> https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#accessing_fields_and_methods
> >>
> >> Thomas Stüfe <thomas.stuefe at gmail.com> schrieb am Mi., 13. Apr. 2022,
> >> 12:22:
> >>
> >>> Hi,
> >>>
> >>> In hotspot, jmethodId is an address to a slot in a table-like
> structure of
> >>> Method*. We ensure that the slot never goes away, so the slot address
> is
> >>> always valid. But we reuse the slot - if a class is unloaded, its
> method
> >>> ids are released by marking their slot with a canary. Later it could
> get
> >>> reused for a different Method*.
> >>>
> >>> I must miss something really obvious, but what prevents an outside
> caller
> >>> from using an invalid or outdated method id via JNI?
> >>>
> >>> If the method id got released, on CallXXXMethod, we stop the VM with a
> >>> fatal JNI error (if CheckJNICalls=1). But there is no way to gracefully
> >>> continue, right?
> >>>
> >>> And what happens if the slot got reused by the VM, so it now contains a
> >>> different Method* ? There is no way catch that, right?
> >>>
> >>> Do both cases just boil down to "the JNI programmer should know when
> class
> >>> unloading did happen, and should not use the jmethodid beyond that
> point"?
> >>>
> >>> Thanks a lot,
> >>>
> >>> Thomas
> >>>
> >>
>
More information about the hotspot-runtime-dev
mailing list