Android系統(tǒng)中 File.listFiles()導(dǎo)致jni crash

最近換工作接手新項(xiàng)目,著手調(diào)查一個(gè)jni crash問(wèn)題。

crash log信息相當(dāng)明顯:

Revision: '0'

ABI: 'arm64'

pid: 5921, tid: 9804, name: Background? >>> com.example.text <<<

signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------

Abort message: 'java_vm_ext.cc:534] JNI DETECTED ERROR IN APPLICATION: input is not valid Modified UTF-8: illegal continuation byte 0xcd'

x0 0000000000000000 x1 000000000000264c x2 0000000000000006 x3 0000000000000008

.....

從這里一看,我們就大概明白和編碼有關(guān)了 因?yàn)槌霈F(xiàn)了關(guān)鍵字?input is not valid Modified UTF-8:

繼續(xù)查看aplog:

08-31 18:34:27.172 5921 9804 F zygote64: java_vm_ext.cc:534] JNI DETECTED ERROR IN APPLICATION: input is not valid Modified UTF-8: illegal continuation byte 0xcd

08-31 18:34:27.172? 5921? 9804 F zygote64: java_vm_ext.cc:534]? ? string: '(3эhi_resource'

08-31 18:34:27.172? 5921? 9804 F zygote64: java_vm_ext.cc:534]? ? input: '0x28 0x33 0xd0 <0xcd> 0x68 0x69 0x5f 0x72 0x65 0x73 0x6f 0x75 0x72 0x63 0x65'

08-31 18:34:27.172? 5921? 9804 F zygote64: java_vm_ext.cc:534]? ? in call to NewStringUTF

08-31 18:34:27.172? 5921? 9804 F zygote64: java_vm_ext.cc:534]? ? from java.lang.String[] java.io.UnixFileSystem.list0(java.io.File)

08-31 18:34:27.172? 5921? 9804 F zygote64: java_vm_ext.cc:534] "Background" prio=5 tid=29 Runnable

08-31 18:34:27.172? 5921? 9804 F zygote64: java_vm_ext.cc:534]? | group="main" sCount=0 dsCount=0 flags=0 obj=0x12d0ac40 self=0x70ff676400

08-31 18:34:27.172? 5921? 9804 F zygote64: java_vm_ext.cc:534]? | sysTid=9804 nice=0 cgrp=default sched=0/0 handle=0x70ff5ff4f0

08-31 18:34:27.172? 5921? 9804 F zygote64: java_vm_ext.cc:534]? | state=R schedstat=( 63854 0 1 ) utm=0 stm=0 core=6 HZ=100

08-31 18:34:27.172? 5921? 9804 F zygote64: java_vm_ext.cc:534]? | stack=0x70ff4fd000-0x70ff4ff000 stackSize=1037KB

08-31 18:34:27.172? 5921? 9804 F zygote64: java_vm_ext.cc:534]? | held mutexes= "mutator lock"(shared held)

08-31 18:34:27.172? 5921? 9804 F zygote64: java_vm_ext.cc:534]? native: #00 pc 00000000003cad9c? /system/lib64/libart.so (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits<char>>&, int, BacktraceMap*, char const*, art::ArtMethod*, void*)+208)

08-31 18:34:27.172? 5921? 9804 F zygote64: java_vm_ext.cc:534]? native: #01 pc 000000000049b124? /system/lib64/libart.so (art::Thread::DumpStack(std::__1::basic_ostream<char, std::__1::char_traits<char>>&, bool, BacktraceMap*, bool) const+348)

08-31 18:34:27.172? 5921? 9804 F zygote64: java_vm_ext.cc:534]? native: #02 pc 00000000002fd7dc? /system/lib64/libart.so (art::JavaVMExt::JniAbort(char const*, char const*)+1048)

08-31 18:34:27.172? 5921? 9804 F zygote64: java_vm_ext.cc:534]? native: #03 pc 00000000002fdbcc? /system/lib64/libart.so (art::JavaVMExt::JniAbortV(char const*, char const*, std::__va_list)+116)

08-31 18:34:27.172? 5921? 9804 F zygote64: java_vm_ext.cc:534]? native: #04 pc 000000000010e764? /system/lib64/libart.so (art::ScopedCheck::AbortF(char const*, ...)+148)

08-31 18:34:27.172? 5921? 9804 F zygote64: java_vm_ext.cc:534]? native: #05 pc 000000000010ec3c? /system/lib64/libart.so (art::ScopedCheck::CheckUtfString(char const*, bool)+736)

08-31 18:34:27.172? 5921? 9804 F zygote64: java_vm_ext.cc:534]? native: #06 pc 000000000010c764? /system/lib64/libart.so (art::ScopedCheck::Check(art::ScopedObjectAccess&, bool, char const*, art::JniValueType*)+644)

08-31 18:34:27.172? 5921? 9804 F zygote64: java_vm_ext.cc:534]? native: #07 pc 0000000000102ec4? /system/lib64/libart.so (art::CheckJNI::NewStringUTF(_JNIEnv*, char const*)+636)

08-31 18:34:27.172? 5921? 9804 F zygote64: java_vm_ext.cc:534]? native: #08 pc 0000000000020c90? /system/lib64/libopenjdk.so (Java_java_io_UnixFileSystem_list0+456)

08-31 18:34:27.172? 5921? 9804 F zygote64: java_vm_ext.cc:534]? native: #09 pc 000000000006f958? /system/framework/arm64/boot-core-oj.oat (Java_java_io_UnixFileSystem_list0__Ljava_io_File_2+152)

08-31 18:34:27.172? 5921? 9804 F zygote64: java_vm_ext.cc:534]? at java.io.UnixFileSystem.list0(Native method)

08-31 18:34:27.172? 5921? 9804 F zygote64: java_vm_ext.cc:534]? at java.io.UnixFileSystem.list(UnixFileSystem.java:313)

08-31 18:34:27.172? 5921? 9804 F zygote64: java_vm_ext.cc:534]? at java.io.File.list(File.java:1122)

08-31 18:34:27.172? 5921? 9804 F zygote64: java_vm_ext.cc:534]? at java.io.File.listFiles(File.java:1248)


我們發(fā)現(xiàn)log 中還是給出了足夠的信息

我們代碼在調(diào)用NewStringUTF()的時(shí)候發(fā)生了crash,原因是utf-8編碼有問(wèn)題,繼續(xù)查看 log:

08-31 18:34:27.172? 5921? 9804 F zygote64: java_vm_ext.cc:534]? ? string: '(????hi_resource'

這里是關(guān)鍵。明顯看的出這里有問(wèn)題。

繼續(xù)查看log 發(fā)現(xiàn) 有File相關(guān)信息出現(xiàn)。發(fā)現(xiàn)是有File調(diào)用下去的

繼續(xù)在我們的業(yè)務(wù)代碼中查找與File相關(guān)的代碼。發(fā)現(xiàn)listFile().

從代碼業(yè)務(wù)分析,我們的代碼關(guān)鍵地方是File.listFile().

public void FileTest(){

FilenameFilter filter =new FilenameFilter() {

@Override

? ? ? ? public boolean accept(File dir, String name) {

? ? ? ? ?return name.endsWith(".txt");

? ? ? ? }

? };

? ? ?File file =new File("xx");

? ? ?file.listFiles(filter);

}

至此懷疑到問(wèn)題發(fā)生點(diǎn),我們驗(yàn)證一下。

既然crash發(fā)生是與utf-8編碼有關(guān),那我們就制造一個(gè)非utf-8命名的文件,制造方法非常簡(jiǎn)單,直接新建一個(gè)txt文件,然后另存為其他文件,保存時(shí)候?yàn)橹形拿?,非utf-8編碼,然后push到手機(jī),在adb下查看該文件,發(fā)現(xiàn)文件名已經(jīng)有問(wèn)題

然后跑業(yè)務(wù)代碼, crash概率100%。

然后我們繼續(xù)正向分析file.listfiles().

調(diào)查過(guò)程非常簡(jiǎn)單?

file.listfiles() ->?list() ->????UnixFileSystem.list() -> list0() ->?UnixFileSystem_md.c.Java_java_io_UnixFileSystem_list0() ->jni_util.c.JNU_NewStringPlatform() ->jni_util_md.c.nativeNewStringPlatform() ->?NewStringUTF().

繼續(xù)利用addr2line反編譯libart.so??


查看Android源代碼:check_jni.cc 2251


check_jni.cc 1276 行


ok,找到關(guān)鍵文件,正是這里拋出jni異常。AbortF().

至此我們斷定crash 從這里拋出。

問(wèn)題發(fā)生原因:

調(diào)用file標(biāo)準(zhǔn)接口的時(shí)候,有l(wèi)istFliles()發(fā)現(xiàn)目錄下有非utf-8編碼的文件名,導(dǎo)致jni crash。

修改方案:在AndroidManifest.xml 中添加 android:debbuggabel="false"

修改原因:這里我也不知道了,?Stackoverflow?中查到的,別問(wèn)我為什么,我也不知道

?猜測(cè)是Android設(shè)置了debbuggabel后,應(yīng)該在調(diào)用newStringUTF()的時(shí)候清楚了異常,所以沒(méi)有這個(gè)crash上報(bào)了。


更多關(guān)于android utf-8知識(shí)看這篇blog,寫(xiě)的還是相當(dāng)不錯(cuò)的

https://blog.csdn.net/self_study/article/details/78886686

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 之前大家一直有推薦簡(jiǎn)書(shū),說(shuō)這個(gè)軟件不錯(cuò)。但是由于時(shí)間精力的有限一直沒(méi)有開(kāi)始使用。今天在開(kāi)192期20組小組會(huì)議的時(shí)...
    八阿哥STAR閱讀 165評(píng)論 0 0
  • 藍(lán)天白云地, 黃土生紅粉。 風(fēng)吹柳蕩起, 桑上又新蟲(chóng)。 看一個(gè)地,有人以“三月”為題,作詩(shī)賽稿,看不順眼,便自己來(lái)...
    遠(yuǎn)曉閱讀 393評(píng)論 7 3
  • 綠楊煙里的舊夢(mèng) 在小河里流淌 青荇柔軟的雙手于水底招搖 游魚(yú)在人群的目光中機(jī)警潛逃 金黃的油菜花田 笑著你最純真的...
    大瘋收閱讀 145評(píng)論 0 1

友情鏈接更多精彩內(nèi)容