PA3.1 etrace
用etrace记录异常处理的踪迹,就在异常响应机制下手即可。在实现异常响应之后,记录异常状态:
- 异常号
- 程序计数器
- 寄存器值
- 异常处理入口地址
// etrace /* 记录异常处理的踪迹 */ void etrace(const char *inst, vaddr_t epc, word_t mcause, word_t gpr, word_t mtvec){ etrace_write("etrace: %s epc = " FMT_WORD ", mcause = "FMT_WORD", gpr(a7) = " FMT_WORD", mtvec = "FMT_WORD "\n", inst, epc, mcause, gpr, mtvec); } #define ETRACE(inst) do { bool success = true; word_t a7 = isa_reg_str2val("a7",&success); assert(success); etrace(inst, read_csrs(CSR_MEPC), read_csrs(CSR_MCAUSE), a7, read_csrs(CSR_MTVEC));} while(0) #define ECALL(dnpc) do { dnpc = isa_raise_intr(ENVIRONMENT_CALL_FROM_U_MODE, s->pc); ETRACE("ecall");} while(0)
但是此时查看日志发现并没有关于etrace的记录。在etrace
函数中,添加printf函数,发现etrace
调用printf函数输出正确信息,但是并没有执行log_write
的指令。
#define log_write(...) IFDEF(CONFIG_TARGET_NATIVE_ELF, \ do { \ extern FILE* log_fp; \ extern bool log_enable(); \ if (log_enable()) { \ fprintf(log_fp, __VA_ARGS__); \ fflush(log_fp); \ } \ } while (0) \ )
最终调试发现是log_enable()
是错误的。继续查看log_enable()
的源码:
bool log_enable() { return MUXDEF(CONFIG_TRACE, (g_nr_guest_inst >= CONFIG_TRACE_START) && (g_nr_guest_inst <= CONFIG_TRACE_END), false); }
那我们先不管g_nr_guest_inst
具体含义直接自定义一个etrace_write()
#define etrace_write(...) IFDEF(CONFIG_TARGET_NATIVE_ELF, \ do { \ extern FILE* log_fp; \ fprintf(log_fp, __VA_ARGS__); \ fflush(log_fp); \ } while (0) \ )
调用此即可实现etrace功能。输出例子如下:
etrace: ecall epc = 0x80001408, mcause = 0x00000008, gpr(a7) = 0xffffffff, mtvec = 0x80001418 etrace: mret epc = 0x8000140c, mcause = 0x00000008, gpr(a7) = 0xffffffff, mtvec = 0x80001418
本文作者:上山砍大树
本文链接:https://www.cnblogs.com/shangshankandashu/p/18543484
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步