工程debug经验

工程项目

Posted by Bruce Lee on 2024-05-31

关于实现指令过程中的debug

1.加载/存储指令调用Mr/Mw宏,Mr/Mw宏是对vaddr_read/vaddr_write函数的封装
注意,关于vaddr_read/vaddr_write函数其中封装的paddr系列函数,以及更深的guest_to_host函数,以及更深的pmem系列函数,以及更深的位于host.h文件中的host_read函数.返回的都是uint32_t.如果读取1/2字节,则自动进行的是无符号扩展.读取4字节,无碍(仅限在32位架构中.(经过2过程,意识到的).关于解决这个bug,第一想法就是写一个新的访寸系列函数,用于返回符号扩展值,其只需要修改的代码处不超过4行,大部分代码是源代码的复制.但是这会大量增加整个程序的代码量.后来使用了在指令模式的"do"代码块中,重新将无符号扩展的值进行剪切,然后有符号扩展.不需要修改其他代码,并且改动处集中.

2.在指令的"do"代码块中,src1/src2/imm默认是无符号运算,而指令的动作默认是有符号运算.(在调试max程序中发现的)

3.U型指令中立即数的左移12位,在immU宏中已经做毕,无需在指令模式的"do"代码块再移动.(在sum调试中发现的),

调试过程:
1.查看程序源码,理解其行为.猜测主要的汇编指令.(在尝试无果后,我甚至改变了程序行为,专项生成我想要观察/调试/验证的汇编指令),首先必须要意识到程序中的check函数的作用,原理,才能去尝试修改程序源码,否则无功而返.

2.查看汇编代码,标记可疑指令.对比HIT GOOD TRAP程序,标记新执行指令.

3.sdb进行定位调试,观察反汇编与汇编指令出入,观察对应的寄存器值是否符合指令执行预期.

4.如果没有发现bug,回到1,重新观察.如果发现了bug,定义其性质,然后到对应的定义性质的代码中去检查.如果检查不出毛病,从enum枚举开始挨个检查.如果还是检查不出毛病,就有意识的修改成错误的bug指令行为,碰出新bug,然后回到3中.

为什么执行了未实现的指令会出现上述报错信息

之前已经分析过整个指令流程以及工作原理.

当一条物理指令在与每一个指令模式匹配过程中,如果都没有匹配上,那么就会匹配到最后inv指令,其指令模式可见,所有未实现/或错误二进制串的指令都会落入inv指令中.

inv指令调用INV宏.(传入当前pc值,用于后续的报告位置)

INV宏调用invalid_inst函数,同样将pc往下传递.

invalid_inst函数就会读取pc值,指令,打印错误信息,寄存器信息,以及提示信息.然后调用set_nemu_state函数,更新nemu状态,置为NEMU_ABORT.

关于mips架构的分支延迟槽技术的编译器应用

检查分支指令的下一条物理指令,如果该指令与分支没有冒险,不修改分支指令的操作数,则可以放入分支延迟槽.

通过重排序,调度器的作用,将并行指令,移位指令或者其他线程指令移动到分支延迟槽中(超标量)

关于指令名对照

手册中确实有伪指令,并且给出其行为,和深度编译后的实际指令.
这个办法确实是有效的.


If you like this blog or find it useful for you, you are welcome to comment on it. You are also welcome to share this blog, so that more people can participate in it. All the images used in the blog are my original works or AI works, if you want to take it,don't hesitate. Thank you !