《MIT 6.828 Lab 1 Exercise 11》实验报告
本实验的网站链接:MIT 6.828 Lab 1 Exercise 11。
题目
The above exercise should give you the information you need to implement a stack backtrace function, which you should call mon_backtrace(). A prototype for this function is already waiting for you in kern/monitor.c. You can do it entirely in C, but you may find the read_ebp() function in inc/x86.h useful. You'll also have to hook this new function into the kernel monitor's command list so that it can be invoked interactively by the user.
The backtrace function should display a listing of function call frames in the following format:
Stack backtrace:
ebp f0109e58 eip f0100a62 args 00000001 f0109e80 f0109e98 f0100ed2 00000031
ebp f0109ed8 eip f01000d6 args 00000000 00000000 f0100058 f0109f28 00000061
...
By studying kern/entry.S you'll find that there is an easy way to tell when to stop.
Implement the backtrace function as specified above.
解答
题目要求打印调用栈的信息,包括ebp和eip寄存器的值、输入参数的值等。
按照提示,我们首先可以调用read_ebp函数来获取当前ebp寄存器的值。ebp寄存器的值实际上是一个指针,指向当前函数的栈帧的底部(而esp寄存器指向当前函数的栈顶)。我们可以把整个调用栈看做一个数组,其中每个元素均为4字节的整数,并以ebp指针的值为数组起始地址,那么ebp[1]存储的就是函数返回地址,也就是题目中要求的eip的值,ebp[2]以后存储的是输入参数的值。由于题目要求打印5个输入参数,因此需要获取ebp[2]~ebp[6]的值。这样第一条栈信息便可打印出来。
那么怎么打印下一条栈信息呢?还得从ebp入手。当前ebp指针存储的恰好是调用者的ebp寄存器的值,因此当前ebp指针又可以看做是一个链表头,我们通过链表头就可以遍历整个链表。举个例子:假设有A、B、C三个函数,A调用B,B调用C,每个函数都对应有一个栈帧,栈帧的底部地址均存储在当时的ebp寄存器中,不妨记为a_ebp, b_ebp和c_ebp,那么将有c_ebp -> b_ebp -> a_ebp,用程序语言表示就是:
a_ebp = (uint32_t *)*b_ebp
和b_ebp = (uint32_t *)*c_ebp
。还有一个问题:怎么知道遍历何时结束呢?题目中提示可以参考
kern/entry.S
,于是我打开此文件,果然找打答案:内核初始化时会将ebp设置为0,因此当我们检查到ebp为0后就应该结束了。
# Clear the frame pointer register (EBP)
# so that once we get into debugging C code,
# stack backtraces will be terminated properly.
movl $0x0,%ebp # nuke frame pointer
- 代码实现
int mon_backtrace(int argc, char **argv, struct Trapframe *tf)
{
uint32_t *ebp;
ebp = (uint32_t *)read_ebp();
cprintf("Stack backtrace:\r\n");
while (ebp)
{
cprintf(" ebp %08x eip %08x args %08x %08x %08x %08x %08x\r\n",
ebp, ebp[1], ebp[2], ebp[3], ebp[4], ebp[5], ebp[6]);
ebp = (uint32_t *)*ebp;
}
return 0;
}
- 输出结果
6828 decimal is 15254 octal!
entering test_backtrace 5
entering test_backtrace 4
entering test_backtrace 3
entering test_backtrace 2
entering test_backtrace 1
entering test_backtrace 0
Stack backtrace:
ebp f010ff18 eip f0100078 args 00000000 00000000 00000000 f010004a f0111308
ebp f010ff38 eip f01000a1 args 00000000 00000001 f010ff78 f010004a f0111308
ebp f010ff58 eip f01000a1 args 00000001 00000002 f010ff98 f010004a f0111308
ebp f010ff78 eip f01000a1 args 00000002 00000003 f010ffb8 f010004a f0111308
ebp f010ff98 eip f01000a1 args 00000003 00000004 00000000 f010004a f0111308
ebp f010ffb8 eip f01000a1 args 00000004 00000005 00000000 f010004a f0111308
ebp f010ffd8 eip f01000dd args 00000005 00001aac f010fff8 f01000bd 00000000
ebp f010fff8 eip f010003e args 00000003 00001003 00002003 00003003 00004003
leaving test_backtrace 0
leaving test_backtrace 1
leaving test_backtrace 2
leaving test_backtrace 3
leaving test_backtrace 4
leaving test_backtrace 5
《MIT 6.828 Lab 1 Exercise 11》实验报告的更多相关文章
- [操作系统实验lab3]实验报告
[感受] 这次操作系统实验感觉还是比较难的,除了因为助教老师笔误引发的2个错误外,还有一些关键性的理解的地方感觉还没有很到位,这些天一直在不断地消化.理解Lab3里的内容,到现在感觉比Lab2里面所蕴 ...
- Ucore lab1实验报告
练习一 Makefile 1.1 OS镜像文件ucore.img 是如何一步步生成的? + cc kern/init/init.c + cc kern/libs/readline.c + cc ker ...
- ucore操作系统学习(三) ucore lab3虚拟内存管理分析
1. ucore lab3介绍 虚拟内存介绍 在目前的硬件体系结构中,程序要想在计算机中运行,必须先加载至物理主存中.在支持多道程序运行的系统上,我们想要让包括操作系统内核在内的各种程序能并发的执行, ...
- 《ucore lab3》实验报告
资源 ucore在线实验指导书 我的ucore实验代码 练习1:给未被映射的地址映射上物理页 题目 完成do_pgfault(mm/vmm.c)函数,给未被映射的地址映射上物理页.设置访问权限的时候需 ...
- 《ucore lab1 exercise5》实验报告
资源 ucore在线实验指导书 我的ucore实验代码 题目:实现函数调用堆栈跟踪函数 我们需要在lab1中完成kdebug.c中函数print_stackframe的实现,可以通过函数print_s ...
- 《ucore lab8》实验报告
资源 ucore在线实验指导书 我的ucore实验代码 练习1: 完成读文件操作的实现(需要编码) 题目 首先了解打开文件的处理流程,然后参考本实验后续的文件读写操作的过程分析,编写在sfs_inod ...
- 《ucore lab7》实验报告
资源 ucore在线实验指导书 我的ucore实验代码 练习1: 理解内核级信号量的实现和基于内核级信号量的哲学家就餐问题(不需要编码) 题目 完成练习0后,建议大家比较一下(可用meld等文件dif ...
- 《ucore lab6》实验报告
资源 ucore在线实验指导书 我的ucore实验代码 练习1: 使用 Round Robin 调度算法(不需要编码) 题目 完成练习0后,建议大家比较一下(可用kdiff3等文件比较软件) 个人完成 ...
- 《ucore lab5》实验报告
资源 ucore在线实验指导书 我的ucore实验代码 练习1: 加载应用程序并执行(需要编码) 题目 do_execv函数调用load_icode(位于kern/process/proc.c中) 来 ...
- 《ucore lab4》实验报告
资源 ucore在线实验指导书 我的ucore实验代码 练习1:分配并初始化一个进程控制块 题目 alloc_proc函数(位于kern/process/proc.c中) 负责分配并返回一个新的str ...
随机推荐
- ubuntu14.0 更改默认python为3.5 并安装tensorflow(cpu)
转:http://blog.csdn.net/qq_27657429/article/details/53482595 第一:安装pip(如果有pip 跳过) #在ubuntu/Linux 64-bi ...
- Java三大特征--多态
1.定义 允许不同类的对象对同一消息做出响应,即同一消息可以根据发送对象的不同而采用多种不同的行为方式. 2.存在条件 2.1存在继承关系 2.2子类重写了父类方法 2.3父类类型的变量指向子类对象的 ...
- 八、linux文件系统上的特殊权限 SUID 、GUID、Sticky
安全上下文 前提:进程有属主和属组,文件有属主和属组 任何一个可执行程序文件能不能启动为进程:取决发起者对程序文件是否拥有执行权限 启动为进程之后,其进程的属主为发起者:进程的属组为发起者所属的组 进 ...
- 为ubuntu安装powerline记录
C:\Users\win10的用户名\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu18.04onWindows_79rhkp1fndgsc\L ...
- 跨域方案JSONP与CORS的各自优缺点以及应用场景
转自 https://www.zhihu.com/question/41992168/answer/217903179 首先明确:JSONP与CORS的使用目的相同,并且都需要服务端和客户端同时支持, ...
- 使用 pip wheel 实现 Python 依赖包的离线安装
pip python 依赖 安装 有时候, 需要部署 Python 应用的服务器没有网络连接, 这时候, 你就要把整个 Python 应用做成离线安装包. 借助 wheel, 很容易就可以实现. 首先 ...
- C# 去除所有的html标签
/// <summary> /// 去除所有的html标签 /// </summary> /// <param name="strhtml">& ...
- oracle赋予一个用户具有查询另一个用户所有表数据
一 以需要被查询的用户登录oracle(假如为A) B为要查询A用户下的表的用户 二 执行查询语句: select 'grant select on A.'|| tname ||' to B ...
- 阶段5 3.微服务项目【学成在线】_day04 页面静态化_10-freemarker静态化测试-基于模板文件静态化
把resource拷贝到test目录下 只保留文件夹结构和test1.ftl这个模板文件就可以了. 新建一个包 编写测试类 使用freemaker提供的方法生成静态文件 Configuration是i ...
- 小记LoadRunner 11 安装VC2005运行环境报错处理
这几天在做性能优化,需要在虚拟机里装个LoadRunner 11.从测试同学那里搞来安装包,按照文档提示安装系统运行环境,提示我要装VC2005 SP1. 安装程序自己安装,报错.截图如下. 于是我又 ...