본문 바로가기

Core BSP 분석/리눅스 커널 핵심 분석

와치독 리셋 - atd daemon

와치독 리셋이 발생하는 디바이스에서 아래와 같은 툼스톤, 즉 유언이 확인되었다.
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_modeminterface.so (request_to_modem_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_lge_ntcode(char*, short, char*, int*)+26)
    #11  pc 0001b92d  /system/lib/libatd_common.so (get_lge_factory_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_modeminterface.so (request_to_modem_via_port+382) // 0x17E
   
바이너리 유틸리티를 사용해서 libatd_modeminterface.so를 파싱하자.
./arm-eabi-objdump -Sdl libatd_modeminterface.so > dump_atd_modem.txt

request_to_modem_via_port란 심볼의 가상 주소는 아래와 같다. 00000ba8에서 0x17E만큼 주소를 더하면, 0xD26이다.
00000ba8 <request_to_modem_via_port>:


request_to_modem_via_port():
/data001/jenkins/SBS9001/recovery/g2mv_tcl_mx_user_cpfusing_13120/android/vendor/lge/factory/atd/modem_interface/nvidia_port/atd_lge_nvidia_port.cpp:170 (discriminator 1)
 d1c:    f04f 0a00     mov.w    sl, #0
strlen():
/data001/jenkins/SBS9001/recovery/g2mv_tcl_mx_user_cpfusing_13120/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_modem_via_port():

정확히 170 라인에서 돌아가신 것이다.
138 int request_to_modem_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 *)modem_atcmd_line, strlen(modem_atcmd_line)+1) <= 0) {
171         DEBUGMSG("[modem_interface] Write to modem port failed in request_to_modem_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_modem_via_port(lgcmd_request*, lgcmd_response*)] get atcmd line : AT%NTCODE?
08-16 20:15:10.776  3858  3878 I Atd     : [int request_to_modem_via_port(lgcmd_request*, lgcmd_response*)] read modem response, count : 1
08-16 20:15:10.785  3858  3878 I Atd     : [request_to_modem_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","

아래는 다른 로그에서 확인한 정상 로그이다.
04-04 15:58:10.060 22442 22471 I Atd     : [NVIDIA] modem_interface_init_status : 0
04-04 15:58:10.060 22442 22471 I Atd     : [int request_to_modem_via_port(lgcmd_request*, lgcmd_response*)] get atcmd line : AT%NTCODE?
04-04 15:58:10.060 22442 22471 I Atd     : [int request_to_modem_via_port(lgcmd_request*, lgcmd_response*)] read modem response, count : 1
04-04 15:58:10.062 22442 22471 I Atd     : [request_to_modem_via_port] response snippet:
04-04 15:58:10.062 22442 22471 I Atd     : "0","FFF,FFF,FFFFFFFF,FFFFFFFF,FF"

last_bugreport.txt-5365-04-28 14:03:27.823   214   376 I Atd     : [int request_to_modem_via_port(lgcmd_request*, lgcmd_response*)] get atcmd line                     : AT%NTCODE?
last_bugreport.txt-5366-04-28 14:03:27.823   214   376 I Atd     : [int request_to_modem_via_port(lgcmd_request*, lgcmd_response*)] read modem res                    ponse, count : 1
last_bugreport.txt:5367:04-28 14:03:27.845   214   376 I Atd     : [request_to_modem_via_port] response snippet:
last_bugreport.txt-5368-04-28 14:03:27.845   214   376 I Atd     : "0","FFF,FFF,FFFFFFFF,FFFFFFFF,FF"

아래 값이 어떻게 찍히는 지,
"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","

정확히 modem_atcmd_line값이 어떤 지 확인이 필요해 보인다.
138 int request_to_modem_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 *)modem_atcmd_line, strlen(modem_atcmd_line)+1) <= 0) {
171         DEBUGMSG("[modem_interface] Write to modem port failed in request_to_modem_via_port: %s\n", strerror(errno));
172         pthread_mutex_unlock(&mAtPortMut);
173
174         return -1;
175     }


스택을 한번 복사해보자.
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