Linux下nemu寄存器怎么打开,基础设施(2)

本文介绍了如何在Linux环境下使用nemu进行基础设施测试,通过建立软件和硬件之间的隔离,利用native架构进行代码验证。强调了在nemu中调试可能遇到的问题,并提出了DiffTest的概念,通过对比nemu与QEMU的执行状态来检测nemu的正确性,减少调试难度。同时,讨论了DiffTest的实现细节,包括如何进行指令级别的对比以及遇到的特殊情况处理。最后,提及了NEMU作为通用程序的性质及其潜在的可能性和挑战。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基础设施(2)

AM作为基础设施

编写klib, 然后在NEMU上运行string程序, 看其是否能通过测试.

表面上看, 这个做法似乎没什么不妥当, 然而如果测试不通过,

你在调试的时候肯定会思考: 究竟是klib写得不对, 还是NEMU有bug呢?

如果这个问题得不到解决, 调试的难度就会上升:

很有可能在NEMU中调了一周, 最后发现是klib的实现有bug.

之所以会有这个问题, 是因为软件(klib)和硬件(NEMU)都是你编写的,

它们的正确性都是不能100%保证的.

大家在中学的时候都学习过控制变量法:

如果能把其中一方换成是认为正确的实现, 就可以单独测试另一方的正确性了!

比如我们在真机上对klib进行测试, 如果测试没通过,

那就说明是klib的问题, 因为我们可以相信真机的硬件实现永远是对的;

相反, 如果测试通过了, 那就说明klib没有问题, 而是NEMU有bug.

一个新的问题是, 我们真的可以很容易地把软件移植到其它硬件上进行测试吗?

聪明的你应该想起来AM的核心思想了: 把程序和架构解耦.

AM的思想保证了运行在AM之上的代码(包括klib)都是架构无关的,

这恰恰增加了代码的可移植性.

想象一下, 如果string.c的代码中有一条只能在NEMU中执行的nemu_trap指令,

那么它就无法在真机上运行.

nexus-am中有一个特殊的架构叫native, 是用GNU/Linux默认的运行时环境来实现的AM API.

例如我们通过gcc hello.c编译程序时, 就会编译到GNU/Linux提供的运行时环境;

你在PA1试玩的超级玛丽, 也是编译到native上并运行.

和$ISA-nemu相比, native有如下好处:

直接运行在真机上, 可以相信真机的行为永远是对的

就算软件有bug, 在native上调试也比较方便(例如可以使用GDB, 比NEMU的monitor方便很多)

因此, 与其在$ISA-nemu中直接调试软件, 还不如在native上把软件调对,

然后再换到$ISA-nemu中运行, 来对NEMU进行测试.

在nexus-am中, 我们可以很容易地把程序编译到另一个架构上运行,

例如在nexus-am/tests/cputest/目录下执行

make ALL=string ARCH=native run

即可将string程序编译到native并运行.

由于我们会将程序编译到不同的架构中, 因此你需要注意make命令中的ARCH参数.

如何生成native的可执行文件

阅读相关Makefile, 尝试理解nexus-am是如何生成native的可执行文件的.

与NEMU中运行程序不同, 由于cputest中的测试不会进行任何输出,

我们只能通过程序运行的返回值来判断测试是否成功.

如果string程序通过测试, 终端将不会输出任何信息;

如果测试不通过, 终端将会输出

make[1]: *** [run] Error 1

当然也有可能输出段错误等信息.

奇怪的错误码

为什么错误码是1呢? 你知道make程序是如何得到这个错误码的吗?

别高兴太早了, 框架代码编译到native的时候默认链接到glibc,

我们需要把这些库函数的调用链接到我们编写的klib来进行测试.

我们可以通过在nexus-am/libs/klib/include/klib.h

中控制是否定义宏__NATIVE_USE_KLIB__, 来控制是否把库函数链接到klib.

若不定义这个宏, 库函数将会链接到glibc, 可以作为正确的参考实现来进行对比.

好了, 现在你就可以在native上测试/调试你的klib实现了,

还可以使用_putc()进行字符输出来帮助你调试, 甚至是GDB.

实现正确后, 再将程序编译到$ISA-nemu(记得移除调试时插入的_putc()), 对NEMU进行测试.

编写可移植的程序

为了不损害程序的可移植性, 你编写程序的时候不能再做一些架构相关的假设了,

比如"指针的长度是4字节"将不再成立, 因为在native上指针长度是8字节,

按照这个假设编写的程序, 在native上运行很有可能会触发段错误.

当然, 解决问题的方法还是有的, 至于要怎么做, 老规矩, STFW吧.

Differential Testing

理解指令的执行过程之后, 添加各种指令更多的是工程实现.

工程实现难免

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值