问题表现
在调试过程中,因为代码bug问题,时常会遇到程序跑飞导致死机/panic问题,此时应用程序已经挂掉,从串口日志的最后打印可以看到,此时程序已跑飞,触发了panic,处于死机状态。
调试方法
第一类:panic
串口日志往上翻,可以找到!!!!!!!!!! Exception !!!!!!!!!!,如下图所示,是这个名为asr_event_listen的task跑飞了。
从!!!!!!!!!! Exception !!!!!!!!!!这一行往下翻一下,可以找到如下图所示的Call stack打印。
这个Call stack就是程序跑飞时的代码执行路径,使用addr2line命令可以反查代码,得到真正的代码文件和行号。命令如下:
addr2line -e out/genie_tg6000a@bes2300wp/binary/genie_tg6000a@bes2300wp.elf -aifp 0xE0000000 0x0C18AEF8 0x0C16D146 0x0C167A58 0x0C168742 0x0C0D138E 0x0C0BB7FC
addr2line命令如下所示,可以看到是挂在了/home/gyl/dev/opencpu/tg6000a1/agui/agcore/agent/AguiAgent.cpp的第107行,找到对应代码行号,查找问题即可。
注意:elf文件和log必须要配套,也就是说必须使用遇到Exception的版本进行解析,否则解析结果可能会偏差影响排查问题。
第二类:Stack Overflow
串口日志往上翻,可以找到!!!!!!!!!! Fatal Error !!!!!!!!!!,如下图所示,是这个名为Zeroconfig的task,其stack空间不够,访问越界了。
这种情况,找到创建这个task的代码,将stacksize调大即可。通过tasklist命令可以看到当前所有task的信息,包括task名字、状态、优先级、stacksize、stack最小可用空间、CPU占用率等。如下所示,tasklist命令执行结果的第5列即为每个task当前的stacksize。
tasklist
[proc_onecmd] ==> enter
------------------------------------------------------------------------
CPU0 usage : 0.75
------------------------------------------------------------------------
Name ID State Prio StackSize MinFreesize Runtime %CPU Candidate
------------------------------------------------------------------------
dyn_mem_proc_task 1 PEND 6 1024 872 0 0.00 N
idle_task 2 RDY 61 4096 1608 4147238 99.25 N
DEFAULT-WORKQUEUE 3 PEND 20 3072 2952 0 0.00 N
timer_task 4 PEND 5 8192 6768 1533 0.00 N
main 5 SLP 33 4096 1220 1548 0.00 N
app_thread 6 PEND 31 4096 1444 1 0.00 N
audio_flinger 7 PEND 30 8192 7760 2879 0.04 N
alsa_deamon 8 PEND 31 16384 13652 71 0.00 N
bes_bt_audio_main 9 PEND 31 10240 10020 0 0.00 N
transq_msg 10 PEND 31 16384 13880 423 0.01 N
apps_recover 12 SLP 33 4096 3936 14 0.00 N
bes_bt_main 13 PEND 31 8704 4552 8593 0.12 N
intersys_rx_thread 14 PEND 31 4096 3828 1653 0.02 N
bes_bt_epta_main 15 SLP 32 4096 3984 191 0.01 N
temp_main 16 SLP 33 4096 1588 9408 0.22 N
main_task 17 PEND 32 8192 4836 1613 0.01 N
net_wq 18 PEND 31 10240 7396 191 0.00 N
net_tasklet 19 PEND 31 8192 6388 655 0.00 N
cw1200_bh 20 PEND 31 4096 720 1610 0.00 N
tcpip_thread 21 PEND 31 25600 22748 3085 0.04 N
wifi_event 22 PEND 32 4096 1008 6 0.00 N
cli-uart 23 RDY 50 8192 4904 143 0.00 Y
ulog 24 PEND 59 4096 1524 1500 0.00 N
watchdog 25 SLP 51 4096 3992 12 0.00 N
DataCenter 27 PEND 33 8192 3116 136 0.00 N
relTimerEngineLoop 28 PEND 33 8192 3552 1839 0.00 N
absTimerEngineLoop 29 PEND 33 8192 7928 0 0.00 N
session 30 PEND 33 8192 1760 639 0.00 N
sessionlow 31 PEND 33 8192 3844 1 0.00 N
AudioManager 32 PEND 33 8192 1728 33 0.00 N
inputLoop 33 PEND 33 8192 4284 0 0.00 N
ctxTrace 34 PEND 33 8192 3244 3 0.00 N
task 36 PEND 33 8192 4188 1 0.00 N
WifiServiceCore 37 PEND 33 8192 3948 51 0.00 N
handleServerRespThread38 PEND 33 8192 3452 31 0.00 N
NetConfigSDK 40 PEND 33 8192 1868 99 0.00 N
recvServerMsgThread41 PEND 33 8192 3896 28 0.00 N
handleServerReqThread42 PEND 33 8192 3988 2 0.00 N
handleClientReqThread43 PEND 33 8192 4004 13 0.00 N
handleClientRespThread44 PEND 33 8192 4268 27 0.00 N
recvClientMsgThread45 PEND 33 8192 4180 2 0.00 N
AuthRedoAction 47 PEND 33 8192 3940 0 0.00 N
AuthAction 49 PEND 33 8192 3964 2 0.00 N
StatusAction 50 PEND 33 8192 3136 19 0.00 N
GattsNetConfigAdapter51 PEND 33 8192 3556 9 0.00 N
btSmImplProcess 52 PEND 33 8192 4060 0 0.00 N
bluetooth_Init_process53 SLP 33 8192 3300 193 0.00 N
btServiceProcess 54 PEND 33 8192 4060 0 0.00 N
GnAlarmClk 55 PEND 33 8192 2064 9 0.00 N
IotMgr 56 PEND 33 8192 3040 97 0.00 N
BTGatt 57 PEND 33 16384 11520 104 0.00 N
GenieLink 59 PEND 33 8192 4140 0 0.00 N
operationLoop 61 PEND 33 8192 3328 19528 0.00 N
Gnlogproducer 62 PEND 36 16384 11508 1258 0.00 N
GnBTgapMsg 63 PEND 33 8192 8016 0 0.00 N
GnAudioService 64 PEND 33 16384 11172 60 0.00 N
ael_manager 65 PEND 32 8192 6532 0 0.00 N
ael_manager 66 PEND 32 8192 2852 33 0.00 N
ael_manager 67 PEND 32 8192 2732 112 0.00 N
GnAudioState 68 PEND 33 32768 20692 49 0.00 N
GnSystemState 69 PEND 33 16384 11252 447 0.01 N
transfer_msg 77 PEND 33 32768 26792 117 0.00 N
h2-send 78 PEND 33 32768 9648 10175 0.17 N
GnOTAmain 79 SLP 33 16384 11964 15 0.00 N
OTAUpgradeLoop 80 PEND 33 8192 2212 21 0.00 N
net 142 PEND 33 8192 2632 81 0.00 N
ble 150 SLP 32 8192 7060 2140 0.02 N
ble 151 SLP 32 3072 2840 747 0.01 N
------------------------------------------------------------------------
[proc_onecmd] ==> leave
第三类:WARNING, malloc failed!!!!
串口日志往上翻,可以找到WARNING, malloc failed!!!!,如下图所示,申请内存需要12288字节,但剩余内存只有591640字节(虽然看起来比12288大很多,但此时内存都碎片化了,已经申请不到一块12288字节长度的连续空闲内存了)
这种情况,说明代码里有内存泄漏,当内存剩余不足时就会触发malloc failed panic。系统提供了一个脚本用于解析内存使用情况,协助排查问题。方法如下:
1、将工具链路径配置到PATH环境变量:
export PATH=toolchain/gcc-arm-none-eabi/Linux64/bin/:$PATH
2、执行脚本,根据elf文件和log文件,解析内存使用情况:
python kernel/tools/debug_tools/coredump_parser_mmleak.py terminal.log out/genie_tg6000a@bes2300wp/binary/genie_tg6000a@bes2300wp.elf > mmleak.log
3、打开刚生成的mmleak.log,先找到内存汇总信息,========== Show MM Statistic Info ==========,如下图所示,可以看到/disksdm/xiya/agui/agutils/src/misc/SimpleBlob.cpp的1105行,共执行了6194次,共分配3189872字节内存,也就基本确定了是这一行代码产生了内存泄漏,排查代码分析问题即可。