各种调试方式的特性

  • 栈回溯无法检查
  • 栈溢出问题
  • 栈不平衡问题(函数调用约定被破坏,导致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部分

第三方库