MIT6.828 lab1/Exercise12

Exercise12

要求

在11的基础上打印出当前eip所指向地址的文件信息,行号,距离上一个eip的地址距离。

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> 

分析

可以根据eip的地址在symbol table中获取这些信息。简称为stab。
symbol table(符号表): 在编译程序中符号表用来存放语言程序中出现的有关标识符的属性信息,这些信息集中反映了标识符的语义特征属性。
Stab汇编指导命令有3种格式:'.stabs'(string), '.stabn'(number)和'.stabd'(dot)。 在MIPS机器上, GCC采用 '.stabn' 输出源程序语句行号的 Stab 调试信息, 而未使用 '.stabd' , 因此, 在MIPS机器上, GCC生成的带有 Stab 调试信息的汇编代码中只含 '.stabs' 和 '.stabn' 两种汇编指导命令, '.stabs' 和 '.stabn' 命令格式如下:

.stabs "STRING", TYPE, OTHER, DESC, VALUE
 
.stabn TYPE, OTHER, DESC, VALUE

TYPE类型:

#define N_GSYM      0x20    // global symbol
#define N_FNAME     0x22    // F77 function name
#define N_FUN       0x24    // procedure name
#define N_STSYM     0x26    // data segment variable
#define N_LCSYM     0x28    // bss segment variable
#define N_MAIN      0x2a    // main function name
#define N_PC        0x30    // global Pascal symbol
#define N_RSYM      0x40    // register variable
#define N_SLINE     0x44    // text segment line number
#define N_DSLINE    0x46    // data segment line number
#define N_BSLINE    0x48    // bss segment line number
#define N_SSYM      0x60    // structure/union element
#define N_SO        0x64    // main source file name
#define N_LSYM      0x80    // stack variable
#define N_BINCL     0x82    // include file beginning
#define N_SOL       0x84    // included source file name
#define N_PSYM      0xa0    // parameter variable
#define N_EINCL     0xa2    // include file end
#define N_ENTRY     0xa4    // alternate entry point
#define N_LBRAC     0xc0    // left bracket
#define N_EXCL      0xc2    // deleted include file
#define N_RBRAC     0xe0    // right bracket
#define N_BCOMM     0xe2    // begin common
#define N_ECOMM     0xe4    // end common
#define N_ECOML     0xe8    // end common (local name)
#define N_LENG      0xfe    // length of preceding entry

使用Exercise11中的例子,加上--gstabs参数,可以得出源代码中的stab信息,其中100代表0x64,对应type的#define N_SO 0x64 // main source file name代表是源文件的名字。

.stabs  "test_stack.c",100,0,2,.Ltext0

68代表0x44,对应#define N_SLINE 0x44 // text segment line number代表bar的行号,其中DESC = 3就代表bar函数在文件中的第三行。

bar:
    .stabn  68,0,3,.LM0-.LFBB1

在程序中stab其实就是一个数据结构,在inc/stab.h下

// Entries in the STABS table are formatted as follows.
struct Stab {
    uint32_t n_strx;    // index into string table of name
    uint8_t n_type;         // type of symbol
    uint8_t n_other;        // misc info (usually empty)
    uint16_t n_desc;        // description field
    uintptr_t n_value;  // value of symbol
};

在程序中是一个stabs[]数组。
在kern/kdebug.c的stab_binsearch函数中,根据eip的地址addr和类型type使用二分查找,找到对应的stabs,然后获取对应的行号的文件信息存入到Eipdebuginfo的数据结构中。

struct Eipdebuginfo {
    const char *eip_file;       // Source code filename for EIP
    int eip_line;           // Source code linenumber for EIP

    const char *eip_fn_name;    // Name of function containing EIP
                    //  - Note: not null terminated!
    int eip_fn_namelen;     // Length of function name
    uintptr_t eip_fn_addr;      // Address of start of function
    int eip_fn_narg;        // Number of function arguments
};

代码

在kern/kdebug.c的debuginfo_eip中添加获取行号的代码

stab_binsearch(stabs, &lline, &rline, N_SLINE ,addr);
    if (lline > rline) 
        return -1;
    info->eip_line = stabs[rline].n_desc;

在kern/monitor.c中添加信息打印

while(ebp) {
        struct Eipdebuginfo debug_info;
        eip = *(ebp+1);
        debuginfo_eip(eip, &debug_info);
        cprintf("ebp %x eip %x args", ebp, eip);
        uint32_t* args = ebp+2;
        for(int i = 0; i < 5; ++i) {
            uint32_t argv = args[i];
            cprintf(" %08x ", argv);
        }
        cprintf("\n");
        cprintf("\t%s:%d: %.*s+%d\n",
            debug_info.eip_file, debug_info.eip_line, debug_info.eip_fn_namelen,
            debug_info.eip_fn_name, eip - debug_info.eip_fn_addr);
        ebp = (uint32_t*)*ebp;
    }

参考

http://caobeixingqiu.is-programmer.com/posts/12361.html
https://github.com/shishujuan/mit6.828-2017/blob/master/docs/lab1-exercize.md

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容