Question about jmethodId and class unloading
Andrei Pangin
andrei.pangin at gmail.com
Fri Apr 15 09:40:56 UTC 2022
Hi,
AFAIK, there is no [legal] way to resolve jmethodID at the time of calling
AsyncGetCallTrace, since this usually happens in a signal handler, and no
JNI / JVM TI Method function is async signal safe. Furthermore, they expect
a thread to be in _thread_in_native state, while an asynchronous signal may
come at any thread state.
Andrei
пт, 15 апр. 2022 г. в 11:44, Thomas Stüfe <thomas.stuefe at gmail.com>:
> 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