Chinaunix首页 | 论坛 | 博客
  • 博客访问: 91363
  • 博文数量: 12
  • 博客积分: 1499
  • 博客等级: 上尉
  • 技术积分: 240
  • 用 户 组: 普通用户
  • 注册时间: 2007-08-20 10:01
文章分类
文章存档

2010年(1)

2008年(11)

我的朋友

分类:

2008-09-30 22:31:20

据说,要学会编程,就应该"read code, and write code". 读了这么久的代码,终于要动手写些东西了。 :-)

实现原理:C函数调用时,首先将参数push入栈,然后push返回地址,接着将原来的EBP push入栈,然后将ESP的值赋给EBP,令ESP指向新的栈顶。而函数返回时,会将EBP的值赋予ESP,然后pop出原来的EBP的值赋予EBP指针。 更详细准确的信息请参考《linux内核完全剖析》一书中的"3.4.1 C函数调用机制"。

由于EBP的内容即为调用它的函数的EBP的地址,因此追踪EBP的值的变化,即可知道函数调用顺序及其他信息。

实现方法:由于代码中已经提供了函数read_ebp(), 因此可以利用来获得当前的EBP的值,即一个内存地址(指针地址)。而该内存地址所保存的值(指针值)即为调用它的函数的EBP地址值。循环比较该变量,直到找到kernel的栈底为止。

判断kernel栈底的方法有两种。假设定义了变量uint32_t *ebp, 则既可比较ebp是否为栈底位置,也可比较*ebp是否为0.
方法1: 文件entry.S中有这样几行:
bootstack:
        .space          KSTKSIZE
        .globl          bootstacktop
可知栈底地址为变量bootstacktop的位置,栈长为KSTKSIZE=32KB。
方法2: 文件entry.S中有如下内容:
        # 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

        # Set the stack pointer
        movl    $(bootstacktop),%esp

        # now to C code
        call    i386_init
可知调用i386_init()时,将值为0的ebp值push到了栈底,因此判断 *ebp==0 既可。

详细实现(使用方法2):
int
mon_backtrace(int argc, char **argv, struct Trapframe *tf)
{
        // Your code here.
        uint32_t *ebp;
        extern char bootstacktop[];

        cprintf("Stack backtrace:\n");

        ebp = (uint32_t *)read_ebp();

        while(ebp < (uint32_t *)bootstacktop){
                cprintf("ebp %08x eip %08x args %08x %08x %08x %08x %08x\n",
                                ebp, *(ebp+1), *(ebp+2), *(ebp+2+1),
                                *(ebp+2+2), *(ebp+2+3), *(ebp+2+4));

                ebp = (uint32_t *)*ebp;

        }

        return 0;
}

将此功能添加到monitor中,只需修改文件kern/monitor.c, 添加以下代码到变量struct Command commands[]中既可:
{ "mon_backtrace", "Backtrace functions call chain", mon_backtrace },

(转贴请注明: by: chunchengfh, from: chunchengfh.cublog.cn)

阅读(2084) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~