lab1_练习5(kdebug.c)

#include <defs.h>
#include <x86.h>
#include <stab.h>
#include <stdio.h>
#include <string.h>
#include <kdebug.h>

#define STACKFRAME_DEPTH 20

extern const struct stab __STAB_BEGIN__[];  // beginning of stabs table
extern const struct stab __STAB_END__[];    // end of stabs table
extern const char __STABSTR_BEGIN__[];      // beginning of string table
extern const char __STABSTR_END__[];        // end of string table

/* debug information about a particular instruction pointer */
struct eipdebuginfo {
    const char *eip_file;                   // source code filename for eip
    int eip_line;                           // source code line number for eip
    const char *eip_fn_name;                // name of function containing eip
    int eip_fn_namelen;                     // length of function's name
    uintptr_t eip_fn_addr;                  // start address of function
    int eip_fn_narg;                        // number of function arguments
};


void
print_debuginfo(uintptr_t eip) {
    struct eipdebuginfo info;
    if (debuginfo_eip(eip, &info) != 0) {
        cprintf("    <unknow>: -- 0x%08x --\n", eip);
    }
    else {
        char fnname[256];
        int j;
        for (j = 0; j < info.eip_fn_namelen; j ++) {
            fnname[j] = info.eip_fn_name[j];
        }
        fnname[j] = '\0';
        cprintf("    %s:%d: %s+%d\n", info.eip_file, info.eip_line,
                fnname, eip - info.eip_fn_addr);
    }
}

static __noinline uint32_t
read_eip(void) {
    uint32_t eip;
    asm volatile("movl 4(%%ebp), %0" : "=r" (eip));
    return eip;
}

void
print_stackframe(void) {
     /* LAB1 YOUR CODE : STEP 1 */
     /* (1) call read_ebp() to get the value of ebp. the type is (uint32_t);
      * (2) call read_eip() to get the value of eip. the type is (uint32_t);
      * (3) from 0 .. STACKFRAME_DEPTH
      *    (3.1) printf value of ebp, eip
      *    (3.2) (uint32_t)calling arguments [0..4] = the contents in address (uint32_t)ebp +2 [0..4]
      *    (3.3) cprintf("\n");
      *    (3.4) call print_debuginfo(eip-1) to print the C calling function name and line number, etc.
      *    (3.5) popup a calling stackframe
      *           NOTICE: the calling funciton's return addr eip  = ss:[ebp+4]
      *                   the calling funciton's ebp = ss:[ebp]
      */

	uint32_t ebp = read_ebp(), eip = read_eip(), args[4];

	int cnt = STACKFRAME_DEPTH;

        //使用ebx用于跟踪调用栈 存各级调用的ebp
	asm volatile (
	"movl %0, %%ebx"
	:
	: "a"(ebp)
	);

        
	while (ebp && cnt--)
	{
                //假设栈段和数据段不同使用了段超越前缀
                //实际在ucore中共享同一个段 可简化
		asm volatile (
	
		"movl %%ss: 8(%%ebx), %0"
		: "=a" (args[0])
		);
		asm volatile (
		"movl %%ss: 16(%%ebx), %0"
		: "=a" (args[1])
		);
		asm volatile (
		"movl %%ss: 24(%%ebx), %0"
		: "=a" (args[2])
			);
		asm volatile (
		"movl %%ss: 32(%%ebx), %0"
		: "=a" (args[3])
			);




		cprintf("ebp:0x%08x eip:0x%08x args:0x%08x", ebp, eip, args[0]);
		int i = 1;
		for (; i < 4; i++)
			cprintf(" 0x%08x", args[i]);
		cprintf("\n");

                //eip为被调函数返回地址
                //eip - 1 处于调用指令call的内部,具体位置不能确定
                //kdebug.c内使用二分搜索确定包含地址eip - 1的函数,即主调函数,并找到调用发生的行 
		print_debuginfo(eip - 1);

		
	     
		ebp = *((uint32_t*)ebp);

		eip = *((uint32_t*)ebp + 1);
		
		asm volatile (
		"movl %0, %%ebx"
		:
		: "a"(ebp)
		);


	}



}

kern/debug/kdebug.c: 306: print_stackframe               +21

函数调用发生的文件   

                                    调用行

                                                     主调函数     

                                                                         调用相对主调函数的offset

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值