You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@harmony.apache.org by Ivan Popov <iv...@gmail.com> on 2007/03/23 17:01:39 UTC

[drlvm][jni] NewGlobalRef() returns NULL for pending exception object

Working on HARMONY-3304 [1] I noticed problem with JNI function
NewGlobalRef() in DRLVM. If it is called for a pending exception
object before ExceptionClear() is invoked, it returns NULL, which is
interpreted as out of memory according to JNI spec [2]. This causes
errors in debug support. In Sun/BEA VM non-NULL reference is returned
in this case.

Simple workaround is to call ExceptionClear() before NewGlobalRef().
However, I'm not sure if ExceptionClear() won't dispose exception
object itself. To my mind it's better to fix NewGlobalRef() and make
it compatible with RI.

Any other opinion?

[1] https://issues.apache.org/jira/browse/HARMONY-3304
[2] http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/functions.html#NewGlobalRef

Thanks.
Ivan

Re: [drlvm][jni] NewGlobalRef() returns NULL for pending exception object

Posted by Pavel Pervov <pm...@gmail.com>.
Ivan,

jthrowable ExceptionOccurred(JNIEnv *env) returns handle to exception. You
can then ExceptionClear() safely and then call to NewGlobalRef() and copy
stored jthrowable into it.

WBR,
-- 
Pavel Pervov,
Intel Enterprise Solutions Software Division

Re: [drlvm][jni] NewGlobalRef() returns NULL for pending exception object

Posted by Ivan Popov <iv...@gmail.com>.
Gregory,

Your are right, reported exception is held by a local reference and
thus cannot be collected. So it's safe to call ExceptionClear() before
NewGlobalRef().

Running Sun's VM with -Xcheck:jni just confirms your words. Invoking
NewGlobalRef() before ExceptionClear() leads to error message:

  FATAL ERROR in native method: JNI call made with exception pending

I just forgot about this useful option, thank you for remanding me.
I'll fix JDWP agent to call ExceptionClear() first.

Thanks.
Ivan

On 3/23/07, Gregory Shimansky <gs...@gmail.com> wrote:
> Ivan Popov wrote:
> > Gregory,
> >
> > Since ExceptionClear() zeroes reference to exception object, it may be
> > collected before subsequent call to NewGlobalRef() can pin it. The
> > only safe way to prevent exception from garbage collection and be able
> > to report it to debugger is to call NewGlobalRef() before
> > ExceptionClear(). I cannot find any other solution.
>
> If you call NewGlobalRef, then you are calling it on some object
> reference, right? If this reference points to an exception object, it
> won't be collected since there is a live reference to it from your code.
> Even if the reference to exception object in TLS is NULL, your code
> holding the reference won't let the object to be collected.
>
> > Though this does not follow well JNI spec (which is quite vague in
> > many points), it works with RI. And I'd like NewGlobalRef() to be
> > fixed and don't return NULL in this case. Do you agree?
>
> Does it work in the same way with -Xcheck:jni?
>
> > On 3/23/07, Gregory Shimansky <gs...@gmail.com> wrote:
> >> Ivan Popov wrote:
> >> > Working on HARMONY-3304 [1] I noticed problem with JNI function
> >> > NewGlobalRef() in DRLVM. If it is called for a pending exception
> >> > object before ExceptionClear() is invoked, it returns NULL, which is
> >> > interpreted as out of memory according to JNI spec [2]. This causes
> >> > errors in debug support. In Sun/BEA VM non-NULL reference is returned
> >> > in this case.
> >>
> >> Actually JNI specification [1] states that only 3 JNI functions may be
> >> safely called in exception state. Looking at the code of NewGloabRef I
> >> see that the check for exception was added at revision 489694 as a
> >> result of committing HARMONY-2817.
> >>
> >> > Simple workaround is to call ExceptionClear() before NewGlobalRef().
> >> > However, I'm not sure if ExceptionClear() won't dispose exception
> >>
> >> ExceptionClear zeroes a reference to exception object in TLS which is
> >> considered as no exception state. The object itself may be collected
> >> later if there are no live references to it left.
> >>
> >> > object itself. To my mind it's better to fix NewGlobalRef() and make
> >> > it compatible with RI.
> >>
> >> [1]
> >> http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/design.html#wp17626
> >>
> >> --
> >> Gregory
> >>
> >>
> >
>
>
> --
> Gregory
>
>

Re: [drlvm][jni] NewGlobalRef() returns NULL for pending exception object

Posted by Gregory Shimansky <gs...@gmail.com>.
Ivan Popov wrote:
> Gregory,
> 
> Since ExceptionClear() zeroes reference to exception object, it may be
> collected before subsequent call to NewGlobalRef() can pin it. The
> only safe way to prevent exception from garbage collection and be able
> to report it to debugger is to call NewGlobalRef() before
> ExceptionClear(). I cannot find any other solution.

If you call NewGlobalRef, then you are calling it on some object 
reference, right? If this reference points to an exception object, it 
won't be collected since there is a live reference to it from your code. 
Even if the reference to exception object in TLS is NULL, your code 
holding the reference won't let the object to be collected.

> Though this does not follow well JNI spec (which is quite vague in
> many points), it works with RI. And I'd like NewGlobalRef() to be
> fixed and don't return NULL in this case. Do you agree?

Does it work in the same way with -Xcheck:jni?

> On 3/23/07, Gregory Shimansky <gs...@gmail.com> wrote:
>> Ivan Popov wrote:
>> > Working on HARMONY-3304 [1] I noticed problem with JNI function
>> > NewGlobalRef() in DRLVM. If it is called for a pending exception
>> > object before ExceptionClear() is invoked, it returns NULL, which is
>> > interpreted as out of memory according to JNI spec [2]. This causes
>> > errors in debug support. In Sun/BEA VM non-NULL reference is returned
>> > in this case.
>>
>> Actually JNI specification [1] states that only 3 JNI functions may be
>> safely called in exception state. Looking at the code of NewGloabRef I
>> see that the check for exception was added at revision 489694 as a
>> result of committing HARMONY-2817.
>>
>> > Simple workaround is to call ExceptionClear() before NewGlobalRef().
>> > However, I'm not sure if ExceptionClear() won't dispose exception
>>
>> ExceptionClear zeroes a reference to exception object in TLS which is
>> considered as no exception state. The object itself may be collected
>> later if there are no live references to it left.
>>
>> > object itself. To my mind it's better to fix NewGlobalRef() and make
>> > it compatible with RI.
>>
>> [1] 
>> http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/design.html#wp17626
>>
>> -- 
>> Gregory
>>
>>
> 


-- 
Gregory


Re: [drlvm][jni] NewGlobalRef() returns NULL for pending exception object

Posted by Ivan Popov <iv...@gmail.com>.
Gregory,

Since ExceptionClear() zeroes reference to exception object, it may be
collected before subsequent call to NewGlobalRef() can pin it. The
only safe way to prevent exception from garbage collection and be able
to report it to debugger is to call NewGlobalRef() before
ExceptionClear(). I cannot find any other solution.

Though this does not follow well JNI spec (which is quite vague in
many points), it works with RI. And I'd like NewGlobalRef() to be
fixed and don't return NULL in this case. Do you agree?

Thanks.
Ivan

On 3/23/07, Gregory Shimansky <gs...@gmail.com> wrote:
> Ivan Popov wrote:
> > Working on HARMONY-3304 [1] I noticed problem with JNI function
> > NewGlobalRef() in DRLVM. If it is called for a pending exception
> > object before ExceptionClear() is invoked, it returns NULL, which is
> > interpreted as out of memory according to JNI spec [2]. This causes
> > errors in debug support. In Sun/BEA VM non-NULL reference is returned
> > in this case.
>
> Actually JNI specification [1] states that only 3 JNI functions may be
> safely called in exception state. Looking at the code of NewGloabRef I
> see that the check for exception was added at revision 489694 as a
> result of committing HARMONY-2817.
>
> > Simple workaround is to call ExceptionClear() before NewGlobalRef().
> > However, I'm not sure if ExceptionClear() won't dispose exception
>
> ExceptionClear zeroes a reference to exception object in TLS which is
> considered as no exception state. The object itself may be collected
> later if there are no live references to it left.
>
> > object itself. To my mind it's better to fix NewGlobalRef() and make
> > it compatible with RI.
>
> [1] http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/design.html#wp17626
>
> --
> Gregory
>
>

Re: [drlvm][jni] NewGlobalRef() returns NULL for pending exception object

Posted by Gregory Shimansky <gs...@gmail.com>.
Ivan Popov wrote:
> Working on HARMONY-3304 [1] I noticed problem with JNI function
> NewGlobalRef() in DRLVM. If it is called for a pending exception
> object before ExceptionClear() is invoked, it returns NULL, which is
> interpreted as out of memory according to JNI spec [2]. This causes
> errors in debug support. In Sun/BEA VM non-NULL reference is returned
> in this case.

Actually JNI specification [1] states that only 3 JNI functions may be 
safely called in exception state. Looking at the code of NewGloabRef I 
see that the check for exception was added at revision 489694 as a 
result of committing HARMONY-2817.

> Simple workaround is to call ExceptionClear() before NewGlobalRef().
> However, I'm not sure if ExceptionClear() won't dispose exception

ExceptionClear zeroes a reference to exception object in TLS which is 
considered as no exception state. The object itself may be collected 
later if there are no live references to it left.

> object itself. To my mind it's better to fix NewGlobalRef() and make
> it compatible with RI.

[1] http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/design.html#wp17626

-- 
Gregory