throwing exceptions in native code

434 views
Skip to first unread message

extrapedestrian

unread,
May 19, 2009, 10:00:30 AM5/19/09
to android-ndk
I wanted to throw exception in native function and catch it in Java.
By looking at the PlatformLibrary SDK example I wrote

if (jclass cls = env->FindClass("java/lang/NullPointerException")) {
env->ThrowNew(cls, "native error");
}

exception is thrown, but Dalvik crashes after it. Exception is not
catch properly.

Can someone tell me please if this is valid behavior of Dalvik VM, or
Im doing somthing else wrong?

e.


Here is LogCat:

05-19 13:48:16.932: WARN/dalvikvm(900): JNI WARNING: JNI method called
with exception raised
05-19 13:48:16.932: WARN/dalvikvm(900): in Lcom/nunc/
edith/edith_library/EdithLibrary;.JAVA_NAV_controller_ProcessKeyBuffer
(Lcom/nunc/edith/edith_library/EdithLibrary$NAV_controller_Info;II
[Lcom/nunc/edith/edith_library/EdithLibrary$NAV_SymbolKey;I)Lcom/nunc/
edith/edith_library/EdithLibrary$NAV_controller_Status; (FindClass)
05-19 13:48:16.932: WARN/dalvikvm(900): Pending exception is:
05-19 13:48:16.942: INFO/dalvikvm(900): Ljava/lang/
NullPointerException;: native error
05-19 13:48:16.942: INFO/dalvikvm(900): at
com.nunc.edith.edith_library.EdithLibrary.JAVA_NAV_controller_ProcessKeyBuffer
(Native Method)
05-19 13:48:16.952: INFO/dalvikvm(900): at
com.nunc.edith.edith_library.EdithLibrary.CreateController
(EdithLibrary.java:294)
05-19 13:48:16.962: INFO/dalvikvm(900): at
com.nunc.edith.edith_library.service.EdithService.onCreate
(EdithService.java:46)
05-19 13:48:16.972: INFO/dalvikvm(900): at
android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:
1123)
05-19 13:48:16.972: INFO/dalvikvm(900): at
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:
2231)
05-19 13:48:16.972: INFO/dalvikvm(900): at
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:
2284)
05-19 13:48:16.972: INFO/dalvikvm(900): at
android.app.ActivityThread.access$1800(ActivityThread.java:112)
05-19 13:48:16.972: INFO/dalvikvm(900): at
android.app.ActivityThread$H.handleMessage(ActivityThread.java:1692)
05-19 13:48:16.983: INFO/dalvikvm(900): at
android.os.Handler.dispatchMessage(Handler.java:99)
05-19 13:48:16.994: INFO/dalvikvm(900): at android.os.Looper.loop
(Looper.java:123)
05-19 13:48:16.994: INFO/dalvikvm(900): at
android.app.ActivityThread.main(ActivityThread.java:3948)
05-19 13:48:17.023: INFO/dalvikvm(900): at
java.lang.reflect.Method.invokeNative(Native Method)
05-19 13:48:17.023: INFO/dalvikvm(900): at
java.lang.reflect.Method.invoke(Method.java:521)
05-19 13:48:17.023: INFO/dalvikvm(900): at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run
(ZygoteInit.java:782)
05-19 13:48:17.023: INFO/dalvikvm(900): at
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:540)
05-19 13:48:17.023: INFO/dalvikvm(900): at
dalvik.system.NativeStart.main(Native Method)
05-19 13:48:17.023: INFO/dalvikvm(900): "main" prio=5 tid=3 NATIVE
05-19 13:48:17.023: INFO/dalvikvm(900): | group="main" sCount=0
dsCount=0 s=0 obj=0x40018e70
05-19 13:48:17.023: INFO/dalvikvm(900): | sysTid=900 nice=0
sched=0/0 handle=-1092744036
05-19 13:48:17.023: INFO/dalvikvm(900): at
com.nunc.edith.edith_library.EdithLibrary.JAVA_NAV_controller_ProcessKeyBuffer
(Native Method)
05-19 13:48:17.023: INFO/dalvikvm(900): at
com.nunc.edith.edith_library.EdithLibrary.CreateController
(EdithLibrary.java:294)
05-19 13:48:17.023: INFO/dalvikvm(900): at
com.nunc.edith.edith_library.service.EdithService.onCreate
(EdithService.java:46)
05-19 13:48:17.023: INFO/dalvikvm(900): at
android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:
1123)
05-19 13:48:17.023: INFO/dalvikvm(900): at
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:
2231)
05-19 13:48:17.023: INFO/dalvikvm(900): at
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:
2284)
05-19 13:48:17.023: INFO/dalvikvm(900): at
android.app.ActivityThread.access$1800(ActivityThread.java:112)
05-19 13:48:17.023: INFO/dalvikvm(900): at android.app.ActivityThread
$H.handleMessage(ActivityThread.java:1692)
05-19 13:48:17.052: INFO/dalvikvm(900): at
android.os.Handler.dispatchMessage(Handler.java:99)
05-19 13:48:17.082: INFO/dalvikvm(900): at android.os.Looper.loop
(Looper.java:123)
05-19 13:48:17.091: INFO/dalvikvm(900): at
android.app.ActivityThread.main(ActivityThread.java:3948)
05-19 13:48:17.111: INFO/dalvikvm(900): at
java.lang.reflect.Method.invokeNative(Native Method)
05-19 13:48:17.111: INFO/dalvikvm(900): at
java.lang.reflect.Method.invoke(Method.java:521)
05-19 13:48:17.111: INFO/dalvikvm(900): at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run
(ZygoteInit.java:782)
05-19 13:48:17.111: INFO/dalvikvm(900): at
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:540)
05-19 13:48:17.111: INFO/dalvikvm(900): at
dalvik.system.NativeStart.main(Native Method)
05-19 13:48:17.111: ERROR/dalvikvm(900): VM aborting
05-19 13:48:17.231: INFO/DEBUG(539): *** *** *** *** *** *** *** ***
*** *** *** *** *** *** *** ***
05-19 13:48:17.231: INFO/DEBUG(539): Build fingerprint: 'generic/sdk/
generic/:1.5/CUPCAKE/147336:eng/test-keys'
05-19 13:48:17.231: INFO/DEBUG(539): pid: 900, tid: 900 >>>
com.nunc.edith.edith_library.service <<<
05-19 13:48:17.231: INFO/DEBUG(539): signal 11 (SIGSEGV), fault addr
deadd00d
05-19 13:48:17.231: INFO/DEBUG(539): r0 00000328 r1 0000000c r2
0000000c r3 00000026
05-19 13:48:17.231: INFO/DEBUG(539): r4 deadd00d r5 43744720 r6
ad083e10 r7 fffe6588
05-19 13:48:17.231: INFO/DEBUG(539): r8 bede04fc r9 41049cb8 10
42383190 fp 00000676
05-19 13:48:17.231: INFO/DEBUG(539): ip ad083eec sp bede0070 lr
afe13e4d pc ad03b5c2 cpsr 20000030
05-19 13:48:17.472: INFO/DEBUG(539): #00 pc 0003b5c2 /
system/lib/libdvm.so
05-19 13:48:17.491: INFO/DEBUG(539): #01 pc 0002deae /
system/lib/libdvm.so
05-19 13:48:17.502: INFO/DEBUG(539): #02 pc 0002e2b4 /
system/lib/libdvm.so
05-19 13:48:17.531: INFO/DEBUG(539): #03 pc 0002ece2 /
system/lib/libdvm.so
05-19 13:48:17.544: INFO/DEBUG(539): #04 pc 00004b90 /
system/lib/libedith.so
05-19 13:48:17.561: INFO/DEBUG(539): #05 pc 00004c08 /
system/lib/libedith.so
05-19 13:48:17.572: INFO/DEBUG(539): #06 pc 0000e3b4 /
system/lib/libdvm.so
05-19 13:48:17.591: INFO/DEBUG(539): stack:
05-19 13:48:17.627: INFO/DEBUG(539): bede0030 00000005
05-19 13:48:17.632: INFO/DEBUG(539): bede0034 00000000
05-19 13:48:17.632: INFO/DEBUG(539): bede0038 afe39f90
05-19 13:48:17.632: INFO/DEBUG(539): bede003c afe39fe4
05-19 13:48:17.632: INFO/DEBUG(539): bede0040 00000000
05-19 13:48:17.643: INFO/DEBUG(539): bede0044 afe13e4d /system/
lib/libc.so
05-19 13:48:17.653: INFO/DEBUG(539): bede0048 0000bc60 [heap]
05-19 13:48:17.653: INFO/DEBUG(539): bede004c afe12e69 /system/
lib/libc.so
05-19 13:48:17.665: INFO/DEBUG(539): bede0050 fffe6588
05-19 13:48:17.665: INFO/DEBUG(539): bede0054 ad083e10
05-19 13:48:17.665: INFO/DEBUG(539): bede0058 43744720
05-19 13:48:17.665: INFO/DEBUG(539): bede005c ad083e10
05-19 13:48:17.685: INFO/DEBUG(539): bede0060 fffe6588
05-19 13:48:17.685: INFO/DEBUG(539): bede0064 afe12ecd /system/
lib/libc.so
05-19 13:48:17.693: INFO/DEBUG(539): bede0068 df002777
05-19 13:48:17.693: INFO/DEBUG(539): bede006c e3a070ad
05-19 13:48:17.693: INFO/DEBUG(539): #00 bede0070 00000001
05-19 13:48:17.693: INFO/DEBUG(539): bede0074 ad02deb3 /system/
lib/libdvm.so
05-19 13:48:17.693: INFO/DEBUG(539): #01 bede0078 ad083e10
05-19 13:48:17.693: INFO/DEBUG(539): bede007c ad02e2b9 /system/
lib/libdvm.so
05-19 13:48:19.101: INFO/ActivityManager(570): Process
com.nunc.edith.edith_library.service (pid 900) has died.
05-19 13:48:19.204: DEBUG/Zygote(541): Process 900 terminated by
signal (11)

Urs Grob

unread,
May 19, 2009, 11:38:57 AM5/19/09
to andro...@googlegroups.com
After you have thrown the exception you shouldn't call most of the JNI
methods (there are a few special methods that are still allowed to be
called). The error you see is because a JNI method was called while
there was already an exception raised.

05-19 13:48:16.932: WARN/dalvikvm(900): JNI WARNING: JNI method called
with exception raised

"Throwing" an exception in native code actually only sets an exception
in a pending state. Once the native code finishes and it returns to
java code this exception is actually thrown.

So after the ThrowNew() call it would be wisest to just return;
Any cleanup you might want to do should be done before you call the
ThrowNew method.

If above error occurs even though you don't call any JNI function
after the exception has been "thrown", then there's already an
exception pending from earlier code. There are methods in JNI that let
you unset a pending Exception so you can continue doing things (like
cleanup that needs JNI calls).

JNI documentation in the net should help with this.
e.g.: http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/jniTOC.html

-- Urs

Urs Grob

unread,
May 19, 2009, 11:41:45 AM5/19/09
to andro...@googlegroups.com
The already pending exception is a NullPointerException:

05-19 13:48:16.932: WARN/dalvikvm(900): Pending exception is:
05-19 13:48:16.942: INFO/dalvikvm(900):
Ljava/lang/NullPointerException;: native error

On Tue, May 19, 2009 at 4:00 PM, extrapedestrian
<extra.pe...@gmail.com> wrote:
>

fadden

unread,
May 19, 2009, 6:12:07 PM5/19/09
to android-ndk
On May 19, 8:38 am, Urs Grob <grob....@gmail.com> wrote:
> JNI documentation in the net should help with this.
> e.g.:http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/jniTOC.html

One small tweak to your comments: the 1.6 spec has a better list of
what you're allowed to do while an exception is pending:

http://java.sun.com/javase/6/docs/technotes/guides/jni/spec/design.html#wp17626

extrapedestrian

unread,
May 22, 2009, 11:44:40 AM5/22/09
to android-ndk
Thanks for your replies.

Some of the environment functions throw exception, and Im trying to
throw exception after it.
I guess I have to dispatch pending exception first, or just skip
sending one again.
>  http://java.sun.com/javase/6/docs/technotes/guides/jni/spec/design.ht...
Reply all
Reply to author
Forward
0 new messages