全部学习汇总: GreyZhang/g_unix: some basic learning about unix operating system. (github.com)
MIT 6.828的课程的确是耗费了我很多时间,光这个lab1就花费了很几天的时间。不过,我觉得这也是一个很好的检验,至少能够让我看得到自己的知识欠缺以及基础的不稳固。今天把mon_backtrace的功能实现作为一个小章节来分析总结一下。
首先,这是功能实现的要求。实现这个函数,能够输出上面的类似结果进行堆栈内容的分析。
其次,增加更加详细的信息可以提示文件、函数以及行号。
关于堆栈监控的分析,前面已经在另一份学习笔记中整理过了,参考:(59条消息) 1620_MIT 6.828 lab1中的堆栈监控实现与分析_grey_csdn的博客-CSDN博客
这部分的实现,其实最主要的一点就是要清楚整个堆栈空间的内容排布。如果知道了这个信息之后,继续下来只是内存信息按照数组的方式进行提取。
文件解析的部分则要比这个复杂很多,但是好的消息是其实用来实验的lab1的JOS系统中已经实现了这样的一个功能,只是欠缺一点信息的处理。
而这样的一个函数,可以通过stabs以及eip的信息解析出来我们需要的详细信息。整个过程,其实是根据eip的数值进行一个大表的二分搜索。Mon_backtrace的实现其实是简单,只是接口调用之后进行成员信息的提取即可。行号以及偏移等附加信息的处理只是最简单的数学操作。而其他的信息处理,则需要了解一下debuginfo_eip的函数实现。
首先,这个函数对传入的eip信息进行初始化,接着从链接器提供的符号信息之中获取stabs的相关信息并进行有效性的检查。检查的手段无非是结尾需要在开始后面这样的简单判断。
接下来就是二分法查找,而查找的过程是层层递进的。
这里是要求实现的部分,但是需要注意:如果按照注释的说明直接赋值为一个右边的索引值,这个数值是错误的。为什么又根据这个进行了二次的解析呢?这得看下面的stabs文档中的相关介绍。
这里画出来的这部分信息明确说明了GCC工具的行为,行号信息会在desc中。
由此,参考这样的数据结构就可以得出最终的设计。
这是修改之后调试过程中的一次记录,此时,代码中的行号还是按照注释中的提示实现的。可以看出来行号全都是0。
而这次是按照文档中的内容修改之后的效果,已经实现了期待的效果。