我在android上有一个使用后台服务(startService)的VOIP应用程序。后台服务负责C / C ++堆栈的创建和生命周期管理。从Android O开始,我在访问线程本地存储时看到崩溃:
#00 pc 000000000004bba8 /system/lib/libc.so (tgkill+12)
#01 pc 000000000001aa13 /system/lib/libc.so (abort+54)
#02 pc 000000000001f2f9 /system/lib/libc.so (__libc_fatal+24)
#03 pc 000000000001aedd /system/lib/libc.so (__assert2+16)
#04 pc 00000000000808ed /data/app/com.myapp.system-TqIMuM73wCvczia_yKDs4g==/lib/arm/libpjsip.so (pj_thread_this+36)
#05 pc 000000000007ffb3 /data/app/com.myapp.system-TqIMuM73wCvczia_yKDs4g==/lib/arm/libpjsip.so (pj_log+610)
#06 pc 0000000000080215 /data/app/com.myapp.system-TqIMuM73wCvczia_yKDs4g==/lib/arm/libpjsip.so (pj_log_5+24)
#07 pc 0000000000087941 /data/app/com.myapp.system-TqIMuM73wCvczia_yKDs4g==/lib/arm/libpjsip.so (pj_timer_heap_destroy+28)
#08 pc 000000000007ad89 /data/app/com.myapp.system-TqIMuM73wCvczia_yKDs4g==/lib/arm/libpjsip.so (pj_dns_resolver_destroy+232)
#09 pc 00000000000dd418 /data/app/com.myapp.system-TqIMuM73wCvczia_yKDs4g==/lib/arm/libMyApp.so
#10 pc 00000000000dd69c /data/app/com.myapp.system-TqIMuM73wCvczia_yKDs4g==/lib/arm/libMyApp.so
我正在使用PJSIP库,它要求在使用之前注册该线程,否则,它会因断言而失败。它在内部使用线程本地存储来管理注册(基于pthread_getspecific,基于pthread_setspecific的注册)。
我已经注册了所有可能访问pjsip API的线程,尤其是:pj_dns_resolver_destroy。但是线程本地存储仍然认为该线程未注册。这仅在Android 8.0+上发生。
这使我想起是否对Android O进行了更改,可能会触发此行为。
更多上下文:
1)可以在两种情况下调用pj_dns_resolver_destroy:网络更改和应用关闭时(即后台服务停止)。
2)我使用基于BroadcastReceiver的网络监视来传递可以调用pj_dns_resolver_destroy的网络更改事件。
其他信息:
服务生命周期以有序的方式处理。 PJSIP提供pj_thread_is_registered来检查线程是否已注册,如果没有注册,则进行声明。我的应用有几种方法可以调用pj_dns_resolver_destroy。
1)网络上的更改(无论应用程序处于前台还是后台)。我们销毁当前的解析器并创建一个新的解析器。检查PJSIP的线程注册后,析构函数将调用pj_dns_resolver_destroy。
2)在应用关闭时(可能在前台或后台),我们从服务的OnDestroy方法中破坏了C ++堆栈。
问题:
Android O w.r.t.是否有任何更改?线程本地存储或具有后台服务等的内存管理,这可能会触发此行为?