harmony-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Evgueni Brevnov" <evgueni.brev...@gmail.com>
Subject Re: [drlvm] Should the launcher print uncaught exceptions?
Date Fri, 13 Oct 2006 10:58:34 GMT
Oliver,

No problems. I agree.

Evgueni

On 10/13/06, Oliver Deakin <oliver.deakin@googlemail.com> wrote:
> Hi Evgueni,
>
> Ive taken a look at the patch - it looks fine to me.
>
> My only comment on:
>  //(*jvm)->DetachCurrentThread(jvm);
>
> is that I believe we need this line to be uncommented to get the correct
> behaviour when running with the IBM VME. As such, I would suggest
> uncommenting this line in the Harmony launcher for those using the
> VME.
> Do you agree?
>
> Regards,
> Oliver
>
>
> Evgueni Brevnov wrote:
> > Oliver,
> >
> > I created https://issues.apache.org/jira/browse/HARMONY-1819 with
> > suggested fix. Please, look at and update it if DetachCurrentThread is
> > required before DestroyJavaVM for some reason.
> >
> > Thanks
> > Evgueni
> >
> > On 9/22/06, Evgueni Brevnov <evgueni.brevnov@gmail.com> wrote:
> >> On 9/22/06, Oliver Deakin <oliver.deakin@googlemail.com> wrote:
> >> > Tim Ellison wrote:
> >> > > Still, it seems strange that you should have to call
> >> DetachCurrentThread
> >> > >  explicitly to get this behavior.  I would have expected that
> >> > > DestroyJavaVM alone would cause the uncaught exception handler to
> >> fire.
> >> > >  Not all apps that embed the VM will know to make this work-around.
> >> > >
> >> >
> >> > Yes, that surprised me too. The bug suggests that the launcher is at
> >> > fault for calling
> >> > ExceptionDescribe() instead of DetachCurrentThread(). However I
> >> would have
> >> > thought that this was not necessary in the case where an exception
> >> > handler has
> >> > been registered, and that the handler would be called during
> >> > DestroyJavaVM()'s
> >> > execution.
> >> >
> >> > Perhaps this is something that could be "fixed" in DRLVM? So if
> >> > DetachCurrentThread() is called, it runs any registered exception
> >> > handlers for that
> >> > thread as usual. However, if DestroyJavaVM is called, it makes sure
> >> that all
> >> > exception handlers are run for every thread.
> >> >
> >>
> >> Sure, I checked both cases work fine on my implementation of
> >> InvocationAPI for DRLVM (with DetachCurrentThread and without it). So
> >> the launcher can choose either to detach the main thread or not...
> >>
> >> Thanks
> >> Evgueni
> >>
> >> > Regards,
> >> > Oliver
> >> >
> >> > > Regards,
> >> > > Tim
> >> > >
> >> > > Oliver Deakin wrote:
> >> > >
> >> > >> Evgueni Brevnov wrote:
> >> > >>
> >> > >>> Oliver,
> >> > >>>
> >> > >>> Yes, I got the same result on RI when starting VM by your
simple
> >> > >>> launcher. Assume it is OK not to print an error message and
stacke
> >> > >>> trace of an unhandled exception in JavaDestroyVM(). How about
> >> calling
> >> > >>> uncaught exception handler? According to the spec it must
be
> >> called if
> >> > >>> terminating thread has an exception. The test shows that the
> >> handler
> >> > >>> is not called when VM is created by our launcher.  But if
VM is
> >> > >>> created by RI's launcher then everything works fine and the
> >> handler is
> >> > >>> executed. This means that RI's launcher somehow deals with
it
> >> (not VM
> >> > >>> itself). It seems for me as a bug in RI. Do you think so?
> >> > >>>
> >> > >> Hi Evgueni,
> >> > >>
> >> > >> I see the same thing - if I run your second Test class (the
> >> > >> UncaughtExceptionHandler
> >> > >> test) with my simple launcher on the RI and J9 I do not see any
> >> output.
> >> > >> i.e. the MyHandler.uncaughtException() method is never called.
> >> > >>
> >> > >> Having a Google around I found a link to a Sun bug registered
> >> for this [1].
> >> > >> All our launcher needs to do is call DetachCurrentThread() on
> >> the main
> >> > >> thread before DestroyJavaVM(), and the UncaughtExceptionHandler
> >> will
> >> > >> be called as expected. (This bug only occurs with exception
> >> handlers
> >> > >> registered to the main thread - I verified this with [2] which
> >> has its
> >> > >> non-main
> >> > >> thread's exception handler called correctly)
> >> > >>
> >> > >> So if you add the line:
> >> > >>   (*jvm)->DetachCurrentThread(jvm);
> >> > >> to my simple launcher just before the DestroyJavaVM() call, you
> >> will see
> >> > >> that the MyHandler.uncaughtException() is called for the main
> >> thread, and
> >> > >> the test works as expected.
> >> > >>
> >> > >> This looks like it needs to be added to our launcher - do you
> >> agree?
> >> > >>
> >> > >> What is even more interesting is that if I run your more simple
> >> Test class
> >> > >> (the one that just does 'throw new Error("my");'), with the
> >> > >> DetachCurrentThread()
> >> > >> call added to the simple launcher I get a stack trace printed
on
> >> both RI
> >> > >> and J9!
> >> > >> Again it appears that this is only a problem with the main
> >> thread (if
> >> > >> you alter
> >> > >> [2] before so that the handler is not registered, you get the
> >> expected
> >> > >> stack trace).
> >> > >> So it seems that adding DetachCurrentThread to the launcher
> >> fixes both
> >> > >> problems!
> >> > >>
> >> > >> Regards,
> >> > >> Oliver
> >> > >>
> >> > >> [1] http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4992454
> >> > >> [2]
> >> > >> public class Test {
> >> > >>    static class MyHandler implements
> >> Thread.UncaughtExceptionHandler {
> >> > >>        public void uncaughtException(Thread t, Throwable e) {
> >> > >>            System.out.println("My Handler Called!!!");
> >> > >>        }
> >> > >>   }
> >> > >>
> >> > >>    static class MyRunnable implements Runnable {
> >> > >>        public void run() {
> >> > >>            Thread.currentThread().setUncaughtExceptionHandler(new
> >> > >> MyHandler());
> >> > >>            throw new Error("my");
> >> > >>        }
> >> > >>    }
> >> > >>
> >> > >>    public static void main(String [] args) {
> >> > >>        Thread t = new Thread(new MyRunnable());
> >> > >>        t.start();
> >> > >>        try {
> >> > >>            t.join();
> >> > >>        } catch (InterruptedException e) {
> >> > >>            System.out.println("Interrupted!");
> >> > >>        }
> >> > >>    }
> >> > >> }
> >> > >>
> >> > >>
> >> > >>> Evgueni
> >> > >>>
> >> > >>> On 9/21/06, Oliver Deakin <oliver.deakin@googlemail.com>
wrote:
> >> > >>>
> >> > >>>> Hi Evgueni,
> >> > >>>>
> >> > >>>> I wrote a simple launcher [1] that does the following:
> >> > >>>> 1) Calls CreateJavaVM
> >> > >>>> 2) Runs the main method of your Test class below
> >> > >>>> 3) Calls DestroyJavaVM
> >> > >>>>
> >> > >>>> Note that it does *not* call env->ExceptionDescribe()
before
> >> destroying
> >> > >>>> the VM.
> >> > >>>> I tested this launcher against the RI and J9 and found
that no
> >> stack
> >> > >>>> trace or
> >> > >>>> error details are printed.
> >> > >>>> So I would say that it is standard behaviour for the VM
not to
> >> output
> >> > >>>> any
> >> > >>>> information about uncaught exceptions when shutting down,
and
> >> that the
> >> > >>>> launcher
> >> > >>>> is expected to call ExceptionDescribe() if it wants any
> >> details to be
> >> > >>>> printed.
> >> > >>>>
> >> > >>>> So from what you have said below, IMHO we need to:
> >> > >>>>  - Change DRLVM to not print stack trace if there is an
uncaught
> >> > >>>> exception at
> >> > >>>> shutdown.
> >> > >>>>  - If necessary, change the launcher to make sure
> >> ExceptionDescribe() is
> >> > >>>> called
> >> > >>>> before DestroyJavaVM().
> >> > >>>>
> >> > >>>> Does that sound right?
> >> > >>>>
> >> > >>>> Regards,
> >> > >>>> Oliver
> >> > >>>>
> >> > >>>> [1]
> >> > >>>> #include <jni.h>
> >> > >>>> main() {
> >> > >>>>    JNIEnv *env;
> >> > >>>>    JavaVM *jvm;
> >> > >>>>    jint result;
> >> > >>>>    jclass cls;
> >> > >>>>    jmethodID mid;
> >> > >>>>
> >> > >>>>    JavaVMInitArgs vmargs;
> >> > >>>>    vmargs.version = 0x00010002;
> >> > >>>>    vmargs.nOptions = 0;
> >> > >>>>    vmargs.ignoreUnrecognized = JNI_TRUE;
> >> > >>>>
> >> > >>>>    result=JNI_CreateJavaVM(&jvm, (void**)&env,
&vmargs);
> >> > >>>>
> >> > >>>>    if (result<0) {
> >> > >>>>        fprintf(stderr, "Cannot create JavaVM\n");
> >> > >>>>        exit(1);
> >> > >>>>    }
> >> > >>>>
> >> > >>>>    cls = (*env)->FindClass(env, "TestClass");
> >> > >>>>
> >> > >>>>    if(cls == NULL)
> >> > >>>>    {
> >> > >>>>        printf("ERROR: FindClass failed.\n");
> >> > >>>>        goto destroy;
> >> > >>>>    }
> >> > >>>>
> >> > >>>>    mid = (*env)->GetStaticMethodID(env, cls, "main",
> >> > >>>> "([Ljava/lang/String;)V");
> >> > >>>>    if(mid==NULL)
> >> > >>>>    {
> >> > >>>>        printf("ERROR: GetStaticMethodID call failed.\n");
> >> > >>>>        goto destroy;
> >> > >>>>    }
> >> > >>>>
> >> > >>>>    (*env)->CallStaticVoidMethod(env, cls, mid, NULL);
> >> > >>>>
> >> > >>>> destroy:
> >> > >>>>    (*jvm)->DestroyJavaVM(jvm);
> >> > >>>> }
> >> > >>>>
> >> > >>>>
> >> > >>>>
> >> > >>>> Evgueni Brevnov wrote:
> >> > >>>>
> >> > >>>>> Hi All,
> >> > >>>>>
> >> > >>>>> I'm almost done with the implementation of Invocation
API for
> >> DRLVM.
> >> > >>>>> While testing it I ran into a problem when an exception
is
> >> printed
> >> > >>>>> twice. I created a simple application which just throws
an
> >> error and
> >> > >>>>> it is not handled by any exception handler:
> >> > >>>>>
> >> > >>>>> public class Test {
> >> > >>>>>    public static void main(String [] args) {
> >> > >>>>>        throw new Error("my");
> >> > >>>>>    }
> >> > >>>>> }
> >> > >>>>>
> >> > >>>>> In this case the launcher calls env->ExceptionDescribe()
before
> >> > >>>>> destroying VM.  Then it calls DestroyJavaVM() which
identifies
> >> > >>>>> unhanded exception and calls an uncaught exception
handler (see
> >> > >>>>> java.lang.Thread.getUncaughtExceptionHandler()) for
the current
> >> > >>>>> thread. By default the handler prints the exception
one more
> >> time.
> >> > >>>>> That's definitely differs from RI where the exception
is
> >> printed out
> >> > >>>>> only once.
> >> > >>>>>
> >> > >>>>> To identify where the problem is I created another
simple
> >> test and
> >> > >>>>> runs it on RI and DRLVM:
> >> > >>>>>
> >> > >>>>> public class Test {
> >> > >>>>>
> >> > >>>>>    static class MyHandler implements
> >> Thread.UncaughtExceptionHandler {
> >> > >>>>>        public void uncaughtException(Thread t, Throwable
e) {
> >> > >>>>>            System.out.println("My Handler Called!!!");
> >> > >>>>>        }
> >> > >>>>>    }
> >> > >>>>>
> >> > >>>>>    public static void main(String [] args) {
> >> > >>>>>        Thread.currentThread().setUncaughtExceptionHandler(new
> >> > >>>>> MyHandler());
> >> > >>>>>        throw new Error("my");
> >> > >>>>>    }
> >> > >>>>> }
> >> > >>>>>
> >> > >>>>> Here is the output:
> >> > >>>>>
> >> > >>>>> RI: java.exe Test
> >> > >>>>> My Handler Called!!!
> >> > >>>>>
> >> > >>>>> DRLVM: java.exe Test
> >> > >>>>> java/lang/Error : my
> >> > >>>>> at Test.main (Test.java: 12)
> >> > >>>>> My Handler Called!!!
> >> > >>>>>
> >> > >>>>> As you can see RI doesn't print exception stack trace
at all.
> >> But
> >> > >>>>> DRLVM does. To be precise the launcher does. So we
need to
> >> fix the
> >> > >>>>> launcher.....
> >> > >>>>>
> >> > >>>>> Note: The behaviour of DRLVM you have may differ from
listed
> >> above
> >> > >>>>> since all experiments were done on my local workspace
with
> >> Invocation
> >> > >>>>> API implemented.
> >> > >>>>>
> >> > >>>>>
> >> ---------------------------------------------------------------------
> >> > >>>>> Terms of use : http://incubator.apache.org/harmony/mailing.html
> >> > >>>>> To unsubscribe, e-mail:
> >> harmony-dev-unsubscribe@incubator.apache.org
> >> > >>>>> For additional commands, e-mail:
> >> harmony-dev-help@incubator.apache.org
> >> > >>>>>
> >> > >>>>>
> >> > >>>>>
> >> > >>>> --
> >> > >>>> Oliver Deakin
> >> > >>>> IBM United Kingdom Limited
> >> > >>>>
> >> > >>>>
> >> > >>>>
> >> ---------------------------------------------------------------------
> >> > >>>> Terms of use : http://incubator.apache.org/harmony/mailing.html
> >> > >>>> To unsubscribe, e-mail:
> >> harmony-dev-unsubscribe@incubator.apache.org
> >> > >>>> For additional commands, e-mail:
> >> harmony-dev-help@incubator.apache.org
> >> > >>>>
> >> > >>>>
> >> > >>>>
> >> > >>>
> >> ---------------------------------------------------------------------
> >> > >>> Terms of use : http://incubator.apache.org/harmony/mailing.html
> >> > >>> To unsubscribe, e-mail:
> >> harmony-dev-unsubscribe@incubator.apache.org
> >> > >>> For additional commands, e-mail:
> >> harmony-dev-help@incubator.apache.org
> >> > >>>
> >> > >>>
> >> > >>>
> >> > >
> >> > >
> >> >
> >> > --
> >> > Oliver Deakin
> >> > IBM United Kingdom Limited
> >> >
> >> >
> >> > ---------------------------------------------------------------------
> >> > Terms of use : http://incubator.apache.org/harmony/mailing.html
> >> > To unsubscribe, e-mail: harmony-dev-unsubscribe@incubator.apache.org
> >> > For additional commands, e-mail: harmony-dev-help@incubator.apache.org
> >> >
> >> >
> >>
> >
> > ---------------------------------------------------------------------
> > Terms of use : http://incubator.apache.org/harmony/mailing.html
> > To unsubscribe, e-mail: harmony-dev-unsubscribe@incubator.apache.org
> > For additional commands, e-mail: harmony-dev-help@incubator.apache.org
> >
> >
>
> --
> Oliver Deakin
> IBM United Kingdom Limited
>
>
> ---------------------------------------------------------------------
> Terms of use : http://incubator.apache.org/harmony/mailing.html
> To unsubscribe, e-mail: harmony-dev-unsubscribe@incubator.apache.org
> For additional commands, e-mail: harmony-dev-help@incubator.apache.org
>
>

---------------------------------------------------------------------
Terms of use : http://incubator.apache.org/harmony/mailing.html
To unsubscribe, e-mail: harmony-dev-unsubscribe@incubator.apache.org
For additional commands, e-mail: harmony-dev-help@incubator.apache.org


Mime
View raw message