問題描述:
XXXX 海外项目待机开机压测时出现死机,遥控器无响应。
问题分析:
出现问题时有产生如下backtrace:
F/libc ( 523):@@@ ABORTING: LIBC: ARGUMENT IS INVALID HEAP ADDRESS IN dlfree addr=0x70ef03a8
#00 pc 0000f13c /system/lib/libc.so
#01 pc 00011ee3 /system/lib/libc.so (dlfree+1458)
#02 pc 0000d053 /system/lib/libc.so (free+10)
#03 pc 00008163 /system/lib/libcutils.so
#04 pc00008f93 /system/lib/libcutils.so (localtime_tz+34)
#05 pc 00048a2b /system/lib/libandroid_runtime.so (android::Time::setToNow()+38)
#06 pc 00063e13 /system/lib/libandroid_runtime.so
壓測一:可以看出是free一個非法堆地址引起的,懷疑有可能調用時傳入了非法參數引起,所以加了debug信息調試,繼續壓測發現傳入參數一切正常,還是出現了上述錯誤。
//下面debug信息正常
I/Log_println( 523):android_text_format_Time_setToNow: TIME: 19000100T000000GMT+10:00(0,0,0,-1,0)
I/Log_Time( 523): Time::setToNow()seconds:0x76512bfc this->t:0x76512c10 timezone:GMT+10:00
I/Log_println( 523):android_text_format_Time_setToNow: timezone: GMT+10:00
排除錯誤。
壓測二:懷疑上述問題和android設置時間有關,android支持GMT[+|-]hh[[:]mm]"和("America/Los_Angeles")兩種時區格式,
修改apk的設置時區方法為("America/Los_Angeles"),初步压测未出現死機,得出如下結論:
当给android设置的时区为"GMT[+|-]hh[[:]mm]"时,会有概率性死机,当给android设置的时区为地区(例如:("America/Los_Angeles"))时则无概率性死机问题(6台机器压测一天没发现)。
壓測三:
定位code:使用arm-linux-androideabi-objdump –s d–l命令分別disassemble cutils.so和libandroid_runtime.so
例如:arm-linux-androideabi-objdump-s -d -l libcutils.so > libcutils.dis
//下面backtrace是添加debug信息引入的,和出現問題的backtrace crash點一致
#03 pc 00008131 /system/lib/libcutils.so
#04 pc 00008fbf /system/lib/libcutils.so (mktime_tz+38)
#05 pc 00048a45 /system/lib/libandroid_runtime.so (android::Time::toMillis(bool)+12)
在libcutils.dis中找到下面信息:
00008f54<mktime_tz>:
mktime_tz():
則 (mktime_tz+38) =00008f54+ 38 = 00008f8b
这里(android::Time::setToNow()+38) 应该是(android::Time::setToNow()+0x26), 所以落点是00008f7a.
00008f8b落在下面區間
/home/xa00087/72668_tcl/Android/android/system/core/libcutils/tztime.c:1166
8f82: 4d6c ldr r5, [pc, #432] ; (9134 <mktime_tz+0x1e0>)
8f84: f50d 6100 add.w r1, sp, #2048 ; 0x800
8f88: 310c adds r1, #12
8f8a: 2201 movs r2, #1
8f8c: 447d add r5, pc
8f8e: 4628 mov r0,r5
8f90: f7ff f878 bl 8084<tzload>
8f94: b130 cbz r0, 8fa4<mktime_tz+0x50>
tztime.c:1166 處代碼如下:
if(tzload(gmt, sp, TRUE) != 0
tztime.c tzload:
if (g_cacheNames[i]) {
free(g_cacheNames[i]);
//出錯,LIBC:ARGUMENT IS INVALID HEAP ADDRESS IN dlfree addr=0x70ef03a8
}
懷疑有reentry 導致導致free了一個無效指針。
添加debug信息進行壓測:
I/Log_println( 521):android_text_format_Time_setToNow: TIME: 19000100T000000GMT+10:00(0,0,0,-1,0)
I/Log_println( 521):android_text_format_Time_setToNow: TIME: 19000100T000000GMT+10:00(0,0,0,-1,0)
I/Log_Time( 521):Time::setToNow() seconds:0x76ab1bfc this->t:0x76ab1c10timezone:GMT+10:00
I/Log_Time( 521):Time::setToNow() seconds:0x7628dbfc this->t:0x7628dc10timezone:GMT+10:00
E/CUTILS ( 521): g_lastCache_before++= 3
E/CUTILS ( 521): g_lastCache_before++= 3
E/CUTILS ( 521): g_lastCache_after++= 4
E/CUTILS ( 521): g_lastCache_after++= 5
E/CUTILS ( 521): g_lastCache= 0
E/CUTILS ( 521): g_lastCache= 0
證明的確存在重入問題。
問題code:
g_lastCache++;
if (g_lastCache>= CACHE_COUNT) {
g_lastCache = 0;
}
i = g_lastCache;
if(g_cacheNames[i]) {
free(g_cacheNames[i]);
g_cacheNames[i] = NULL;//add by ys
}
此題懷疑是android源碼的一個bug,"GMT[+|-]hh[[:]mm]"格式設置時區是時序上存在問題,會存在上面接口的重入問題。
解決方案:
1. 使用("America/Los_Angeles")時區格式;(4台TV压测48小时OK)
2. 調用setToNow()時添加互斥控制;