go x/mobile:进程因JNI异常在下一次调用之前未被清理而崩溃,

busg9geu  于 6个月前  发布在  Go
关注(0)|答案(2)|浏览(103)

你使用的Go版本是什么(go version)?

go1.8.3
(
gomobile版本 +0f31740 Wed Apr 19 17:20:05 2017 +0000 (android); androidSDK=[removed]/platforms/android-26
)

你使用的操作系统和处理器架构是什么(go env)?

linux/amd64
cross compiled to
android/arm

你做了什么?

从Android应用程序的Go部分调用Java函数(带接口),并在Java端抛出了一个未检查的异常。
这是原始崩溃日志的缩略版:

07-15 21:00:20.352 2854-2854/? A/DEBUG: Abort message: 'art/runtime/java_vm_ext.cc:410] JNI DETECTED ERROR IN APPLICATION: JNI CallStaticVoidMethod called with pending exception java.lang.IllegalStateException: Already closed'
07-15 21:00:20.352 2854-2854/? A/DEBUG:     x0   0000000000000000  x1   00000000000027c8  x2   0000000000000006  x3   0000000000000000
07-15 21:00:20.352 2854-2854/? A/DEBUG:     x4   0000000000000000  x5   0000000000000001  x6   0000000000000000  x7   0000000000000000
07-15 21:00:20.352 2854-2854/? A/DEBUG:     x8   0000000000000083  x9   000000000002fc80  x10  0000000001deffa0  x11  0000000001df00e0
07-15 21:00:20.352 2854-2854/? A/DEBUG:     x12  0000000000000000  x13  0000007fa1344000  x14  0000000000000000  x15  0000000000000000
07-15 21:00:20.352 2854-2854/? A/DEBUG:     x16  0000007fa1336568  x17  0000007fa12c92fc  x18  0000007fa1347f50  x19  0000007f81433500
07-15 21:00:20.352 2854-2854/? A/DEBUG:     x20  0000007f81433440  x21  000000000000000b  x22  0000000000000006  x23  0000007f823f4400
07-15 21:00:20.352 2854-2854/? A/DEBUG:     x24  0000007f979afc80  x25  0000000000000000  x26  0000007f9dcec000  x27  0000000000000000
07-15 21:00:20.352 2854-2854/? A/DEBUG:     x28  0000007f823f4400  x29  0000007f814328e0  x30  0000007fa12c6a98
07-15 21:00:20.352 2854-2854/? A/DEBUG:     sp   0000007f814328e0  pc   0000007fa12c9304  pstate 0000000020000000
07-15 21:00:20.357 2854-2854/? A/DEBUG: backtrace:
07-15 21:00:20.357 2854-2854/? A/DEBUG:     #00 pc 0000000000069304  /system/lib64/libc.so (tgkill+8)
07-15 21:00:20.357 2854-2854/? A/DEBUG:     #01 pc 0000000000066a94  /system/lib64/libc.so (pthread_kill+68)
07-15 21:00:20.357 2854-2854/? A/DEBUG:     #02 pc 00000000000239f8  /system/lib64/libc.so (raise+28)
07-15 21:00:20.357 2854-2854/? A/DEBUG:     #03 pc 000000000001e198  /system/lib64/libc.so (abort+60)
07-15 21:00:20.357 2854-2854/? A/DEBUG:     #04 pc 00000000004336c0  /system/lib64/libart.so (_ZN3art7Runtime5AbortEv+324)
07-15 21:00:20.357 2854-2854/? A/DEBUG:     #05 pc 0000000000136f78  /system/lib64/libart.so (_ZN3art10LogMessageD2Ev+3176)
07-15 21:00:20.357 2854-2854/? A/DEBUG:     #06 pc 000000000030f248  /system/lib64/libart.so (_ZN3art9JavaVMExt8JniAbortEPKcS2_+2080)
07-15 21:00:20.357 2854-2854/? A/DEBUG:     #07 pc 000000000030f6c8  /system/lib64/libart.so (_ZN3art9JavaVMExt9JniAbortVEPKcS2_St9__va_list+116)
07-15 21:00:20.357 2854-2854/? A/DEBUG:     #08 pc 0000000000142d34  /system/lib64/libart.so (_ZN3art11ScopedCheck6AbortFEPKcz+144)
07-15 21:00:20.357 2854-2854/? A/DEBUG:     #09 pc 0000000000149be4  /system/lib64/libart.so (_ZN3art11ScopedCheck5CheckERNS_18ScopedObjectAccessEbPKcPNS_12JniValueTypeE.constprop.116+6088)
07-15 21:00:20.358 2854-2854/? A/DEBUG:     #10 pc 000000000015c8f0  /system/lib64/libart.so (_ZN3art8CheckJNI11CallMethodVEPKcP7_JNIEnvP8_jobjectP7_jclassP10_jmethodIDSt9__va_listNS_9Primitive4TypeENS_10InvokeTypeE+948)
07-15 21:00:20.358 2854-2854/? A/DEBUG:     #11 pc 000000000015d72c  /system/lib64/libart.so (_ZN3art8CheckJNI20CallStaticVoidMethodEP7_JNIEnvP7_jclassP10_jmethodIDz+160)
07-15 21:00:20.358 2854-2854/? A/DEBUG:     #12 pc 00000000004f8038  /data/app/org.kkdev.v2raygo-1/lib/arm64/libgojni.so (go_seq_inc_ref+80)

我已经成功地重现了这个崩溃。尝试使用以下二进制apk(启用了调试):
app.zip

  • 重现的日志:*

https://gist.github.com/xiaokangwang/8d7f5aefd98d7c52c644b4c815097eb5

  • 重现代码:*

重现的Go部分
https://github.com/xiaokangwang/gomobilecrashreproducego
Java部分的重现
https://github.com/xiaokangwang/gomobilecrashreproducejava

你期望看到什么?

优雅地处理这种情况,例如一个处理未检查异常的API,它可以是:

  • 一个接收未检查异常的通道,如果没有定义,则默认处理。
  • 一个运行时设置,用于定义在这种情况下要做什么(退出或放手)。
  • 如果没有定义策略并且抛出了异常,则在控制台/日志中显示警告消息。

你看到了什么?

只是崩溃,并破坏整个应用程序。
这个问题也在ethereum/go-ethereum#14437被发现,但似乎被忽略了。
最初发现是因为我的应用程序的服务经常崩溃,使其无法使用。

yzckvree

yzckvree1#

为什么不从Java返回一个错误到Go端?这样,异常就会自动转换为Go错误。

c90pui9n

c90pui9n2#

一些错误是由Android或开发人员无法控制的代码触发的。我找到的唯一解决方案是在所有Java接口中使用try和catch,希望异常不会导致崩溃。

相关问题