본문 바로가기

Core BSP 분석/커널 트러블슈팅

tombstone - __strlen_chk

와치독 리셋이 발생하는 디바이스에서 아래와 같은 툼스톤, 즉 유언이 확인되었어요.
backtrace:
    #00  pc 000221c8  /system/lib/libc.so (tgkill+12)
    #01  pc 000131c9  /system/lib/libc.so (pthread_kill+48)
    #02  pc 000133dd  /system/lib/libc.so (raise+10)
    #03  pc 00012113  /system/lib/libc.so
    #04  pc 00021a7c  /system/lib/libc.so (abort+4)
    #05  pc 00012bf9  /system/lib/libc.so
    #06  pc 00012c0f  /system/lib/libc.so
    #07  pc 00023af7  /system/lib/libc.so (__strlen_chk+18)
    #08  pc 00000d27  /system/lib/libatd_mdminterface.so (request_to_mdm_via_port+382)
    #09  pc 0001af4b  /system/lib/libatd_common.so (request_to_system(int, char const*, int, char*, int*, int*)+254)
    #10  pc 0001d033  /system/lib/libatd_common.so (read_pompeii_ntcode(char*, short, char*, int*)+26)
    #11  pc 0001b92d  /system/lib/libatd_common.so (get_pompeii_sw_version(int, char*, int*)+1588)
    #12  pc 000158a9  /system/lib/libatd_common.so (system_write_version_info()+64)
    #13  pc 00006a93  /system/bin/atd
    #14  pc 0000d358  /system/lib/libc.so (__thread_entry+72)
    #15  pc 0000d4f0  /system/lib/libc.so (pthread_create+240)
 
정확히 어디서 어보트가 발생하였는 지 확인하는게 중요한데요. 우선 아래 콜 스택을 점검해보았어요.
    #07  pc 00023af7  /system/lib/libc.so (__strlen_chk+18)
    #08  pc 00000d27  /system/lib/libatd_mdminterface.so (request_to_mdm_via_port+382) // 0x17E
 
바이너리 유틸리티를 사용해서 libatd_mdminterface.so를 파싱할 수 있는데요.
./arm-eabi-objdump -Sdl libatd_mdminterface.so > dump_atd_mdm.txt
 
request_to_mdm_via_port란 심볼의 가상 주소를 확인할 수 있어요. 00000ba8에서 0x17E만큼 주소를 더하면, 0xD26군요.
00000ba8 <request_to_mdm_via_port>:
 
request_to_mdm_via_port():
/src/android/vendor/atd/at_command_port.cpp:170 (discriminator 1)
 d1c:    f04f 0a00     mov.w    sl, #0
strlen():
/src/android/bionic/libc/include/string.h:226 (discriminator 1)
 d20:    4620          mov    r0, r4
 d22:    f44f 7180     mov.w    r1, #256    ; 0x100
 d26:    f7ff ed92     blx    84c <__strlen_chk@plt>
request_to_mdm_via_port():
 
정확히 170 라인에서 돌아가셨는데요.
138 int request_to_mdm_via_port(struct lgcmd_request *req, struct lgcmd_response *rsp)
139 {
140     int ret = -1;
141     int loop_count = 0;
142     char modem_atcmd_line[4096] = {0,};
...
170     if (write(fd_nv_port, (void *)mdm_atcmd_line, strlen(modem_atcmd_line)+1) <= 0) {
171         DEBUGMSG("[pompeii_interface] Write to modem port failed in request_to_mdm_via_port: %s\n", strerror(errno));
172         pthread_mutex_unlock(&mAtPortMut);
173
174         return -1;
175     }
 
죽기 전에 토해낸 디바이스의 다른 로그를 확인해 볼까요? 여기서 26으로 시작하는 엄청난 스트링이 어디서 찍히는 지 확인해보죠.
08-16 20:15:10.776  3858  3878 I Atd     : [int request_to_mdm_via_port(lgcmd_request*, cmd_response*)] get atcmd line : AT%NTCODE?
08-16 20:15:10.776  3858  3878 I Atd     : [int request_to_mdm_via_port(lgcmd_request*, cmd_response*)] read modem response, count : 1
08-16 20:15:10.785  3858  3878 I Atd     : [request_to_mdm_via_port] response snippet: 
"26","334,03F,FFFFFFFF,FFFFFFFF,FF","334,030,FFFFFFFF,FFFFFFFF,FF","704,03F,FFFFFFFF,FFFFFFFF,FF","704,030,FFFFFFFF,FFFFFFFF,FF","706,04F,FFFFFFFF,FFFFFFFF,FF","706,040,FFFFFFFF,FFFFFFFF,FF","710,30F,FFFFFFFF,FFFFFFFF,FF","710,300,FFFFFFFF,FFFFFFFF,FF","
 
tombstone에서 스택 주소 근처의 메모리 덤프를 볼 수 있는데, 이 값을 Trace32 시뮬레이터를 써서 올려볼 수 있어요.
아래 명령어로요.
D.S SD:0xC0001000 %LE %LONG 0xb67323d8 0x00000000 0x00000000 0x000f1ec9 0x00008000 0x00000000 0x00000000 0x00000000  0x00000006 0x0000006e 0x00000f26 0xb6e34fea  0xb6e34fea 0xb6eda1cd 0x00000006 0x00000000  0xb6ea3004 0xb6eda3e1 0xb6732424 0xb6ed9117 0x00000000 0xffffffdf 0x00000000 0x00000000  0x00000000 0x00000000 0x00000000 0xb6f09cfb  0xb67336d8 0xb6ee8a80 0x4fc7b724 0xb6ed9bfd 0xb6f07927 0xb6732464 0x01000000 0xb6ed9c13 0xb6f07927 0xb6f09cfb 0x01000000 0x4e255400  0x00000100 0xb6eeaafb 0xb673249c 0xb6e34d2b 0xb6e3538f 0xb673249c 0x00000000 0xb6f16384  0xb6e35230 0xb6e353c0 0x00000000 0x32220a0d 0x222c2236 0x2c343333 0x2c463330 0x46464646 0x46464646 0x4646462c 0x46464646 0x46462c46 0x33222c22 0x302c3433 0x462c3033 0x46464646
 
그러면 아래와 같이 스택 공간에 로딩되어 있는 헥사값을 확인할 수 있어요.
_______0________4________8________C_0123456789ABCDEF
B67323D8 00000000 00000000 000F1EC9 .#s.............
00008000 00000000 00000000 00000000 ................
00000006 0000006E 00000F26 B6E34FEA ....n...&....O..
B6E34FEA B6EDA1CD 00000006 00000000 .O..............
B6EA3004 B6EDA3E1 B6732424 B6ED9117 .0......$$s.....
00000000 FFFFFFDF 00000000 00000000 ................
00000000 00000000 00000000 B6F09CFB ................
B67336D8 B6EE8A80 4FC7B724 B6ED9BFD .6s.....$..O....
B6F07927 B6732464 01000000 B6ED9C13 'y..d$s.........
B6F07927 B6F09CFB 01000000 4E255400 'y...........T%N
00000100 B6EEAAFB B673249C B6E34D2B .........$s.+M..
B6E3538F B673249C 00000000 B6F16384 .S...$s......c..
B6E35230 B6E353C0 00000000 32220A0D 0R...S........"2
222C2236 2C343333 2C463330 46464646 6","334,03F,FFFF
46464646 4646462C 46464646 46462C46 FFFF,FFFFFFFF,FF
33222C22 302C3433 462C3033 46464646 ","334,030,FFFFF
 
해당 담당자에게 위 정보를 공유했더나 바로 코드 수정을 해서 문제는 사라졌어요.
물론 코드 정보를 알려주지 않았는데 스트링을 쪼개서 전달했나봐요.