各种调试方式的特性
- 栈回溯无法检查
- 栈溢出问题
- 栈不平衡问题(函数调用约定被破坏,导致callee的pop流程产生问题)
- 由于强制上访导致的HardFault
- 栈随机化可以检查:栈溢出问题
- 栈水位与栈深度估计可以检查:栈溢出问题、栈浪费问题
栈回溯与CmBacktrace
- 先在cmb_cfg.h进行配置
- 基本函数
- cm_backtrace_init()
- cmb_get_sp():获取当前sp指针
- cm_backtrace_call_stack(call_stack, sizeof(call_stack),cmb_get_sp())
- 获取当前的调用栈信息
- cm_backtrace_assert(uint32_t sp)
- 传入当前sp,并触发assert,一般在需要断言/手动触发异常的地方调用
- sp可以用在c中用asm获取
- cm_backtrace_fault(uint32_t fault_handler_lr, uint32_t fault_handler_sp)
- 传入当前sp和lr,并触发fault,一般在FaultHandler中调用
- sp和lr可以用在c中用asm获取
- 根据可执行文件,用指令地址找到对应代码行数
- 使用addr2line.exe工具/通过符号表来查询
- 使用easylogger来直接断言或输出
栈水位与栈深度估计
日志EasyLogger
- 基本函数
- log_a()/log_e()/log_w()/log_i()/log_d()/log_v()等:直接打印log
- assert()与elog_assert_set_hook():当断言表达式不成立时,会输出日志或者执行断言钩子
- elog_set_output_enabled()/elog_output_lock_enabled():日志使能与失能/日志锁使能与使能
- elog_set_fmt(日志类型,样式):设置输出类型与样式
- elog_flush():必须启动缓冲模式才能使用,会将缓冲区的日志输出,一般用于FreeRTOS移植
- 还有过滤、颜色、查找等
日志RTTViewer
非侵入式调试
Fault调试
- 见ARM内核概论的Fault部分