JOS学习笔记(四)

原创 2013年02月28日 22:19:43

Lab1还差最后一部分,就是给出具体的调试信息,如下面所示:

K> backtrace
Stack backtrace:
  ebp f010ff78  eip f01008ae  args 00000001 f010ff8c 00000000 f0110580 00000000
         kern/monitor.c:143: monitor+106
  ebp f010ffd8  eip f0100193  args 00000000 00001aac 00000660 00000000 00000000
         kern/init.c:49: i386_init+59
  ebp f010fff8  eip f010003d  args 00000000 00000000 0000ffff 10cf9a00 0000ffff
         kern/entry.S:70: <unknown>+0
K>


和上次的montacktrace相比,增加了eip所在的源文件、对应的源文件行数、函数名以及在相对于该函数地址后的汇编代码的地址偏移。

首先明确,这个功能既然能实现,那么肯定在某个地方以某种方式地方记录着eip和源文件之间的相互对应的信息。

而这个存储的地方就是stab表。

首先使用objdump -G 查看一下kernel生成的obj(obj/kern/kernel)中stab表中的内容,如下:

前5列是stab,第六列不知道含义,第七列对应stabstr,换句话说这个表会原封不动的读入内存,stab部分的地址就是kdebug.c里的__stab_begin__,后面字符串地址就是__stabstr_begin__。

这个表很直观,根据类型不同在某些行(用index表示)会给出一个地址与源文件的对应关系(SO),紧接着给出这个源文件中的函数地址和函数名的对应关系(FUN),之后是这个函数里的每一行(SLINE)和地址偏移的对应关系。

而我们所要做的就是读取这些关系并显示出来。

 

问题1 这个表何时以何种方式加入的内存。

 

很遗憾kdebug.c里面stab表的地址符号是extern进来的,我并没有找到这个符号第一次出现的位置,不过估计应该是和内核一起,通过elf头的文件信息加载进来的,但具体加载到了哪里我没有深究。

 

问题2 如何对这个表进行检索。

 

庆幸的是,Jos很“友好”的给我们提供了一个检索函数:stab_binsearch。函数接受4个参数,第一是stab总表(这个说法并不是很恰当,虽然函数的含义是传入一个总表,但其实只要传入表中的一项当做起始位置函数也能正常工作),第二第三是表的下标的范围,代表在这个下标范围内寻找,若找到了,则第二个参数赋值为相应的表的下标,若没有找到,则right>left,第四个参数传入要寻找的表项的类型,也就是上面图的第二列。第五个参数代表要寻找的值,也就是上面图中的第五列,根据这个值寻找表项。而且为了比较高效,这个函数还是个二分搜索的。更加详细的说明函数注释都解释的很清楚。

 

问题3 我们需要做什么

需要做的是完成debuginfo_eip,该函数传入一个eip值,通过这个eip查找所需信息,并放入Eipdebuginfo这个结构体里。

JOS比较“友好”,已经替我们完成了很多功能了,我们只需要使用stab_binsearch找到函数地址和源文件行数对应的关系就行了。

代码如下:

之前的代码已经找到了函数地址,并且已经将addr减去了这个函数地址得到了函数内偏移,查找结果会放在lline里,根据这个index访问stab表即可。

之后修改backtrace函数,按要求显示相应信息即可,然后运行结果大概如下:

 

值得注意的是,对应源文件,发现“行数”指向的并不是很正确,有时候会多向下指几行。

这是因为在查找stab时候,我们是根据eip进行查找,而eip的内容就是指向下一条将要执行的指令的地址,所以“行数”的不准是正常的合乎逻辑的。

当然要修正这个“bug”使之更符合我们的调试习惯也并不难,只要把查找到的lline改成lline-1,即寻找上一行源代码即可。

但因为实验貌似要求就是根据eip找到相应的位置,所以我也并没有改。

 

至此lab1就结束了,本来想一两周就写完的,没想到断断续续拖了好几个月。

5年前刚接触编程的时候编的第一个程序就是printf("hello,world!");,然后学习断点调试,可直到今天我才大概明白了这看上去如此“简单”而不值得一提的功能实现起来需要多少的技术水平。任何看起来“理所当然”的东西实现或者证明起来都是相当难的,数学和计算机技术都佐证了这一点。

所谓返璞归真的境界,大概就是如此吧。

JOS lab4 用户程序分析

JOS lab4 用户程序分析 faultread.c faultdie.c: 这两个用户程序一起分析 左右两个用户程序,都试图对非法地址写入数据,但是左边的就会导致 page fault ,...
  • u011368821
  • u011368821
  • 2015年04月24日 22:43
  • 1363

JOS 系统中第一个用户进程的建立和运行

一:进程的表示: 在jos系统里面,进程用一个struct结构体Env来存储相应的信息,这个ENV的结构体有点类似于进程描述符一类的东西。 struct Env { struct Trapfram...
  • fang92
  • fang92
  • 2015年09月11日 21:22
  • 825

JOS lab3 部分用户程序分析

JOS lab4 部分用户程序分析 在lab 4的分支里面,会有各种好玩的用户程序.如下: 觉得还是有必要一一对其进行简要的分析.自顶向下的了解OS的机制 分析的用户程序顺序随意,不按照...
  • u011368821
  • u011368821
  • 2015年04月21日 19:35
  • 1696

JOS学习笔记(八)

神说、内核要有自己的数据、使用户不可访问.事就这样成了。  神称高地址为内核空间、称低地址为用户空间. 神看着是好的。  神说、用户要有自己的进程、和自己的页表、并可以进行系统调用.事就这样成了。...
  • ROger__wonG
  • ROger__wonG
  • 2013年03月28日 23:49
  • 6862

MIT 操作系统实验 MIT JOS lab4

MIT JOS lab4 写在前面的碎碎念~ :          经历了LAB 3的洗礼,死磕到了lab 4. 这里还是首先向各位为JOS 实验做过笔记,写过博客,把自己实验代码托管到J...
  • u011368821
  • u011368821
  • 2015年04月17日 16:01
  • 6025

MIT 操作系统实验 MIT JOS lab3

MIT JOS lab3
  • u011368821
  • u011368821
  • 2015年02月15日 02:54
  • 6306

JOS 系统调用的过程

系统调用,是用户态进程转向内核态的一种安全机制,在保证了内核空间安全并且不被破坏的的前提下,让用户态程序可以实现一定的功能。 通过JOS系统,来看系统调用的具体过程。 系统调用,在语言层面来看,其实可...
  • fang92
  • fang92
  • 2015年09月14日 20:15
  • 1239

MIT 操作系统实验 MIT JOS lab1

JOS lab1
  • u011368821
  • u011368821
  • 2014年10月03日 23:03
  • 8465

MIT 操作系统实验 MIT JOS lab5

MIT 操作系统实验 MIT JOS lab5 Lab 5: File system, Spawn and Shell Disk Access            The x86 proc...
  • u011368821
  • u011368821
  • 2015年04月28日 20:48
  • 3540

JOS学习笔记(九)

LAB3代码已经上传。 最近忙于打WOWTCG,早就做完了一直没腾出时间写博客。 LAB3第二部分主要是处理系统调用。 第一部分我们已经让第一个env运行了起来,接着这个env执行一个cprin...
  • ROger__wonG
  • ROger__wonG
  • 2013年04月10日 23:37
  • 5597
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:JOS学习笔记(四)
举报原因:
原因补充:

(最多只允许输入30个字)