在系统运行或调试过程中,程序总是出现一些出乎意料的现象(例如程序异常或者某个任务运行不是预料的)。为了帮助用户快速定位问题,减少出现问题难以定位的情况,操作系统中的栈回溯功能就显得十分重要。
栈回溯到底是什么?又该如何使用呢?下面让我们一起来详细了解一下吧!(学会了这一招,以后遇到难以定位的问题还怕啥?)
一、栈及栈回溯
1.1 栈的作用
1)传递函数参数:为了速度快,使用CPU的寄存器传递参数。这会碰到一个问题,CPU寄存器的数量是有限的,当函数参数超过约定的CPU寄存器个数时,则使用栈存储剩余的参数,来实现传递函数参数。
2)保存局部变量:函数里面必然要使用到局部变量,而不能总是用全局变量。
3)函数调用时的上下文:为了保证函数调用后能够正确返回,需要保存函数调用时的寄存器和返回地址。
4)任务切换时的上下文:在发生任务切换时,需要保存任务上下文,保证切换回任务时程序正常运行。
5)发生中断时的上下文:发生中断时,为了保证正确返回,需要保存当时的上下文。
1.2 栈回溯的基本功能
从栈的作用可以看出栈中保存着函数的返回地址,我们可以通过编译程序的铁定规则或者程序的特殊指令识别出这些返回地址。再从这些返回地址来确定函数的调用关系、调用顺序。我们通过栈回溯可以查看当前的上下文。栈回溯主要适用于以下场景:
1)在异常、中断和任务等上下文查看任务栈回溯;
2)如果异常发生在中断上下文还可以对中断栈回溯;
3)对于运行任务不仅支持对其他任务进行栈回溯还可以对自身进行栈回溯;
4)在中断上下文查看中断栈回溯。
1.3 支持架构
OneOS目前支持ARM v6m,v7m,v8m三种架构的所有单板和RISC-V部分单板。
二、使用方法
2.1 使用方法1-函数调用
OneOS主要提供以下接口供应用程序使用:
接口 |
说明 |
task_stack_show |
显示任务栈回溯信息 |
interrupt_stack_show |
显示中断栈回溯信息 |
task_stack_show
该函数用于显示任务栈回溯信息,由于异常上下文和其他上下文压栈的内容不一样,因此添加了一个context参数。函数原型如下:
os_err_t task_stack_show(os_task_t *task, os_uint32_t context);
interrupt_stack_show
该函数用于显示中断栈回溯信息,原型如下:
os_err_t interrupt_stack_show(void);
参数 |
说明 |
无 |
无 |
返回 |
说明 |
OS_ERROR |