有时die()/panic()流程不一定能正常走完,可能走到某一步又发生了异常,则就形成了嵌套,这种情况,我们一般不会关注后面的异常,而是关注最开始的那个异常。
为了避免异常嵌套,在发生第2次异常时,我们就拦截下来,我们在3个地方用于拦截nested panic:
- do_PrefetchAbort()
- do_DataAbort()
- do_undefinstr()
拦截后不走die()/panic()流程,因为这些流程可能会再次发生异常,走我们写的函数aee_stop_nested_panic()函数:
在里面尽量少用kernel模块,很有可能也会发生异常,仅仅将寄存器等重要信息输出到ram console就等死(死循环等等看门狗复位!)。这时你抓回来的db里的SYS_LAST_KMSG就可以看到这些资料,大致如下(不同版本稍有区别):
里面包含了寄存器信息、堆栈信息和调用栈,我们就可以通过工具(addr2line)还原当时异常的位置。
不过nested panic能参考的信息很少,不像普通的KE那样丰富。