死机问题举例
手动写一个错误的shell指令为例:调用rt_device_read接口,但传入的设备句柄为空指针、接收缓存为空指针。
执行shell指令触发断言错误。
假设我们不知道程序执行到何处时触发的断言错误,以及为何触发了断言,需要对问题进行定位,步骤如下:
排查步骤:
1. 找到错误日志
RTT会在每个断言错误触发后在控制台打印是哪个函数的哪个位置触发的断言错误:
2. 根据日志中的函数名和行号找到对应的断言错误代码

可以看到是执行rt_device_read函数时dev参数传入了一个null触发了断言。
但此时还不知道rt_device_read是被何处调用的。
3. 在断言前添加if
在断言前添加一个条件与断言相反的if语句。
目的是为了debug时打断点,如果直接断点打到断言的话,执行正确或错误时都会被打断,不便于调试,换成if就可以仅在执行执行错误时被断点打断,同时还可以添加一些调试信息输出。
如果运行的环境不支持debug打断点,可以在if中把执行函数的线程名打出来,也能方便定位问题代码。
4. Debug中打断点

这里需要注意,if内需要是一个不会被编译器优化的可执行的语句,例如不要就写一行代码int a = 0;
打上断点以后等待问题复现触发断点。
5. 触发断点后查看调用栈
触发断点时即为触发了原断言错误的情况,打开调用栈窗口:
6. 逐层排查函数调用
在调用栈窗口,右键点击函数名,点击show caller code,可以查看每一级函数是在哪里被调用的。
针对示例问题,在已经确认是dev参数传入了null导致了断言错误的情况下,从当前函数逐个向上层排查,看是在那一层传参错误导致的即可。
向上跳转一层后可以看到是assert_test()中调用的rt_device_read(),传递的dev参数是空指针。
问题找到。
相关文章:
RT-Thread线程调度机制、线程切换时机分析:
https://blog.csdn.net/weixin_43854928/article/details/119985822
[RTT] RT-Thread Hard Fault 死机问题定位方法:
https://blog.csdn.net/weixin_43854928/article/details/123997001?spm=1001.2014.3001.5502