Android 在 libicuuc.so 中神秘崩溃(utext_close)

标签 android str-replace icu

最新更新后,我们的 Android 游戏开始在 Google Play ANR 和崩溃部分记录奇怪的崩溃。

backtrace:
  #00  pc 000000000011be50  /system/lib64/libicuuc.so (utext_close_60+52)
  #01  pc 00000000001aa4c4  /system/lib64/libicui18n.so (icu_60::RegexPattern::zap()+212)
  #02  pc 00000000001aa560  /system/lib64/libicui18n.so (icu_60::RegexPattern::~RegexPattern()+36)
  #03  pc 0000000000094120  /system/framework/arm64/boot-core-libart.oat (offset 0x90000) (java.math.NativeBN.BN_copy [DEDUPED]+160)
  #04  pc 000000000018340c  /system/framework/arm64/boot-core-libart.oat (offset 0x90000) (libcore.util.NativeAllocationRegistry$CleanerThunk.run+76)
  #05  pc 000000000040c754  /system/framework/arm64/boot.oat (offset 0x13b000) (sun.misc.Cleaner.clean+164)
  #06  pc 00000000001daa0c  /system/framework/arm64/boot.oat (offset 0x13b000) (java.lang.ref.ReferenceQueue.enqueueLocked+236)
  #07  pc 00000000001dab2c  /system/framework/arm64/boot.oat (offset 0x13b000) (java.lang.ref.ReferenceQueue.enqueuePending+172)
  #08  pc 00000000001d7b04  /system/framework/arm64/boot-core-libart.oat (offset 0x90000) (java.lang.Daemons$ReferenceQueueDaemon.runInternal+244)
  #09  pc 000000000015978c  /system/framework/arm64/boot-core-libart.oat (offset 0x90000) (java.lang.Daemons$Daemon.run+76)
  #10  pc 00000000002c1038  /system/framework/arm64/boot.oat (offset 0x13b000) (java.lang.Thread.run+72)
  #11  pc 000000000056ef88  /system/lib64/libart.so (art_quick_invoke_stub+584)
  #12  pc 00000000000d4204  /system/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+200)
  #13  pc 0000000000472fd4  /system/lib64/libart.so (art::(anonymous namespace)::InvokeWithArgArray(art::ScopedObjectAccessAlreadyRunnable const&, art::ArtMethod*, art::(anonymous namespace)::ArgArray*, art::JValue*, char const*)+104)
  #14  pc 0000000000474090  /system/lib64/libart.so (art::InvokeVirtualOrInterfaceWithJValues(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jmethodID*, jvalue*)+424)
  #15  pc 000000000049f684  /system/lib64/libart.so (art::Thread::CreateCallback(void*)+1120)
  #16  pc 0000000000083588  /system/lib64/libc.so (__pthread_start(void*)+36)
  #17  pc 00000000000241dc  /system/lib64/libc.so (__start_thread+68)

更新中唯一与此相关的更改代码是在我们的分析模块中,我们正在其中进行一些字符串替换:

private static String formatStringForAnalytics(String str) {
    if(str == null) {
        return "";
    }

    return str.replaceAll(" ", "_").replaceAll(":", "");
}

我们自己无法重现崩溃情况。因此,我们必须等待一段时间才能制作并发布新的更新,在该更新中我们禁用这段代码,看看崩溃是否消失。

我只是觉得标准字符串替换会导致这样的事情很奇怪。还有其他人遇到过类似的崩溃吗?

最佳答案

问题实际上是错误的字符串替换函数。

API 文档说 replaceAll() 方法

Replaces each substring of this string that matches the given regular expression with the given replacement.

我更改了代码以使用 replace() 方法

Replaces each substring of this string that matches the literal target sequence with the specified literal replacement sequence.

这实际上是代码最初打算做的事情。通过此更改,崩溃消失了。

似乎当某些字符串登录到分析中时 replaceAll()设法以某种方式折断绳子并导致其崩溃。 This answer关于 replace() 之间差异的问题和replaceAll()在这种情况下似乎确实是非常正确的:使用错误的函数可能会导致微妙的错误。

关于Android 在 libicuuc.so 中神秘崩溃(utext_close),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61342981/

相关文章:

c++ - 提升语言环境的特定于语言环境的 to_lower 问题

makefile - 使用 mingw 命令卡住构建 ICU

android - Pygame 在 Android 上发送图像真的很慢

android - 为什么Google map Api key需要经常更换

android - 如何将标签样式设置为带有彩色文本的浅色主题?

php - 以编程方式替换 PHP 数组中值的表示

android - 从 Intent (或从 SL4A)开始 Android 测试?

php - str_replace() 与 foreach、大写和精确单词匹配

string - Matlab中使用strrep替换多个子字符串

iPhone 应用因使用 ICU(Unicode 扩展)而被拒绝