LiteOS大揭秘【02】:你一定不知道,LiteOS竟偷偷隐藏了这些调测功能
作为物联网应用开发者,以上场景是不是很熟悉。日常开发工作中,难免会碰到bug导致系统异常崩溃/卡死的情况。踩内存、死锁、内存泄漏……开发中总会有各种坑等着你。在不额外增加打印、不用gdb单步调试等情况下,有没有什么方法能定位出问题原因?为帮助开发者找到bug原因,LiteOS提供了一系列的调测功能,比如异常接管、临终遗言。
异常接管
异常接管作为一种调测手段,可以在串口上输出异常发生时的日志,包括异常类型、寄存器信息、栈回溯信息(可以得到函数调用过程)、异常时正在执行的任务信息(如任务名、任务号、栈大小)、所有未退出的任务信息(包括任务名、任务号、栈大小、状态等)、内存信息等。用户可以根据寄存器内容,追溯函数间的调用关系,再辅以任务信息和内存信息,定位分析问题。通过地址越界写,构造的异常打印如下:
********Hello Huawei LiteOS******** -------系统运行的基本信息 Processor : Cortex-A7 * 2 Run Mode : SMP GIC Rev : GICv2 build time : Apr 5 2020 05:36:22 ********************************** main core booting up... osAppInit cpu0 is in exc. cpu1 is running. data_abort fsr:0x829, far:0x00000000 --------异常类型信息 Abort caused by a write instruction. Domain fault, section excType:data abort taskName = osMain --------异常时正在运行的任务信息 taskID = 64 task stackSize = 0 system mem addr = 0x80324fc0 excBuffAddr pc = 0x8021cd5c excBuffAddr lr = 0x8021cd5c excBuffAddr sp = 0x802c0998 excBuffAddr fp = 0x802c09d4 R0 = 0xf --------异常时寄存器信息 R1 = 0x802b5410 R2 = 0x0 R3 = 0x80283590 R4 = 0x0 R5 = 0x64 R6 = 0x80200000 R7 = 0x8fe4a198 R8 = 0x8ff4f7d8 R9 = 0x8fe42ef0 R10 = 0x2 R11 = 0x802c09d4 R12 = 0xf CPSR = 0x600f01d3 *******backtrace begin******* --------异常时的调用栈信息 traceback 0 -- lr = 0x802c09f0 fp = 0x802b5410 -------异常时系统中所有任务的运行状态 Name TaskEntryAddr TID Affi CPU Priority Status StackSize WaterLine ------------ ------------- --- ---- ---- -------- ------- --------- ----------- CpupGuardCreator 0x802228b0 0x0 0x0001 -1 0 Ready 0x800 0x14c Swt_Task 0x80216708 0x1 0x0001 -1 0 Ready 0x6000 0x14c IdleCore000 0x802171c0 0x2 0x0001 -1 31 Ready 0x800 0x14c WowWriteFlashTask 0x802736bc 0x3 0x0003 -1 30 Ready 0x6000 0x14c system_wq 0x8023ec80 0x4 0x0003 -1 1 Ready 0x6000 0x14c app_Task 0x8021e05c 0x5 0x0001 -1 10 Ready 0x6000 0x14c StackPoint TopOfStack EventMask SemID CPUUSE CPUUSE10s CPUUSE1s MEMUSE ---------- ---------- --------- ----- -------- ------------ ----------- --------- 0x80349998 0x803492e0 0x0 0xffffffff 0.0 0.0 0.0 0 0x8035f9f0 0x80359b38 0x0 0xffffffff 0.0 0.0 0.0 0 0x80360250 0x8035fb98 0x0 0xffffffff 0.0 0.0 0.0 0 0x80366268 0x803603b0 0x0 0xffffffff 0.0 0.0 0.0 0 0x8036c358 0x803664a0 0x0 0xffffffff 0.0 0.0 0.0 0 0x80372368 0x8036c4b0 0x0 0xffffffff 0.0 0.0 0.0 0 stack name cpu id stack addr total size used size --------异常堆栈信息 ---------- ------- ---------- ---------- ---------- udf_stack 1 0x802bc850 0x28 0x0 udf_stack 0 0x802bc878 0x28 0x0 abt_stack 1 0x802bc8a0 0x28 0x0 abt_stack 0 0x802bc8c8 0x28 0x24 fiq_stack 1 0x802bc970 0x40 0x0 fiq_stack 0 0x802bc9b0 0x40 0x0 svc_stack 1 0x802bc9f0 0x2000 0x0 svc_stack 0 0x802be9f0 0x2000 0x524 irq_stack 1 0x802bc8f0 0x40 0x0 irq_stack 0 0x802bc930 0x40 0x0 exc_stack 1 0x802c09f0 0x1000 0x0 exc_stack 0 0x802c19f0 0x1000 0x48 dump mem around R1:0x802b5410 --------异常发生时内存信息 0x802b53d0 :00000000 00000000 00000000 00000000 0x802b53e0 :00000000 00000000 00000000 00000000 0x802b53f0 :00000000 00000000 00000000 00000000 0x802b5400 :80283874 80283874 00000000 00000000 0x802b5410 :8032d800 00000000 8035fb48 00000000 0x802b5420 :00000002 00000000 00000000 00000001 0x802b5430 :00000000 00000002 8032d850 00000000 0x802b5440 :00000000 00000000 00000000 00000000 dump mem around R3:0x80283590 0x80283550 :00000000 00000000 ffffffff 00000000 0x80283560 :802007a4 00000001 00001f01 00000000 0x80283570 :00000000 00000000 00000000 00001f01 0x80283580 :00000000 00000000 00000000 00000000 0x80283590 :80000000 00000000 80221820 00000000 0x802835a0 :ffffffff 00000000 80200864 00000000 0x802835b0 :ffffffff 00000000 80200878 00000000 0x802835c0 :ffffffff ffffffff ffffffff ffffffff dump mem around R6:0x80200000 0x801fffc0 :41db90ff 4bbf1c18 b9a7c011 b5109e98 0x801fffd0 :255268df dd8910f9 aa75ab2e 5597a885 0x801fffe0 :35903762 76be3268 cb98dc45 35f6bde7 0x801ffff0 :b985a5ea 3d86aad9 7621d9d9 7accda85 0x80200000 :ea0035e6 ea0036e1 ea0036e3 ea0036eb 0x80200010 :ea0036ee ea0036f1 ea003697 ea0036f3 0x80200020 :8021b19c 8021b108 8026c4cc 8022c6ec 0x80200030 :8026ceb0 80276364 8027843c 00000000 dump mem around R11:0x802c09d4 0x802c0994 :80221938 00000002 802c09d4 0000000f 0x802c09a4 :600f01d3 802c0998 802c09d4 802c09ec 0x802c09b4 :80221820 802b5410 00000004 802c09ec 0x802c09c4 :80221e08 8029043c 00000000 802b5410 0x802c09d4 :802c09f0 00000000 00000000 00000064 0x802c09e4 :80200000 8fe4a198 8020dcb0 cccccccc 0x802c09f4 :cacacaca cacacaca cacacaca cacacaca 0x802c0a04 :cacacaca cacacaca cacacaca cacacaca dump mem around SP:0x802c0998 0x802c0958 :802c096c 80283590 802c0994 802191b4 0x802c0968 :80201b84 80201b84 00000000 80283590 0x802c0978 :802c29ac 802c09d4 00000009 802c29ac 0x802c0988 :80202cfc 80202cd4 802c09c4 80221938 0x802c0998 :00000002 802c09d4 0000000f 600f01d3 0x802c09a8 :802c0998 802c09d4 802c09ec 80221820 0x802c09b8 :802b5410 00000004 802c09ec 80221e08 0x802c09c8 :8029043c 00000000 802b5410 802c09f0 system memcheck over, all passed!
异常接管只能在串口上即时输出日志,当日志过多时用户可能无法看到完整的日志内容。为解决这个问题,LiteOS提供了“临终遗言”功能,可以将日志保存在NOR flash(非易失闪存)中,同时用户也可以注册自己的日志读写函数。系统复位重启后,在串口命令行中输入相应的命令,已记录的日志就会被打印出来。
CPU占用率
考虑到有些异常情况下,可能不会触发上面的系统异常处理流程,比如系统运行卡顿,LiteOS提供了查看CPU占用率的功能。LiteOS的CPU占用率,采用任务记录的方式。在任务切换时,记录任务启动时间和切出时间;任务切出或者退出时间,系统还会累加整个任务的占用时间。CPU占用率分为系统CPU占用率和任务CPU占用率两种。
系统CPU占用率 = 系统中除空闲任务外其他任务运行总时间 / 系统运行总时间。
系统CPU占用率用于表示系统一段时间内的闲忙程度,也表示CPU的负载情况。
任务CPU占用率 = 任务运行总时间 / 系统运行总时间。
任务CPU占用率用于表示单个任务在一段时间内的闲忙程度。
用户通过系统和各个任务的CPU占用率,可以找到导致系统卡顿的某个或某几个任务,同时也能据此判断任务的设计是否符合预期。相关代码在kernel/extended/cpup/目录下,下面是LiteOS中看到的CPU占用率效果图:
LiteOS的调测百宝箱,针对踩内存、内存泄漏、野指针释放等问题,提供了一系列的内存调测能力;针对互斥锁死锁问题,提供了死锁检测能力。除此之外,还有对任务、中断、队列、信号量、软件定时器等各种事件的跟踪调测功能。这些调测功能,均已安排在小编的工作日程中,不久后小编就会陆续揭开它们的神秘面纱,希望能给开发者带来更多帮助和支持。
- 点赞
- 收藏
- 关注作者
评论(0)