一、dump_stack(堆栈转储)作用:主要用于内核调试,打印内核堆栈段信息。

二、使用前便已内核时:使用前,先在内核配置中把kernel debug选上:

make menuconfig:
kernel hacking-->
kernel debug三、arch/x86/kernel/dumpstack.c
void dump_stack(void){
unsigned long bp=0;
unsigned long stack;
#ifdef CONFIG_FRAME_POINTER
if(!bp)
get_bp(bp);
#endif
printk("pid:%d,comm:%20s %s %s %.*s/n",current->pid,current->comm,print_tainted(),init_utsname()->release,(int)strcspn(init_utsname()->version,init_utsname()->version);
show_trace(NULL,NULL&stack,bp);
}

 

dump_stack不准确的原因分析

   kernel panic后打印的堆栈信息是调用dump_stack函数获得的。而dump_stack的原理是遍历堆栈,把所有可能是内核函数的内容找出来,并打印对应的函数。因为函数调用时会把下一条指令的地址放到堆栈中。所以只要找到这些return address,就可以找到这些return address所在函数,进而打印函数的调用关系。 
         但是dump_stack可能不准确,可能的原因有三: 
         1.所有这些可以找到的函数地址,存在/proc/kallsyms中。它并不包括内核中所有的函数,而只包括内核中stext~etext和sinittext~einittext范围的函数,及模块中的函数。详细可参考scripts/kallsyms.c 
         2.一些函数在编译时进行了优化,把call指令优化为jmp指令,这样在调用时就不会把return address放到堆栈,导致dump_stack时在堆栈中找不到对应的信息。 
         3.堆栈中可能有一些数值,它们不是return address,但是在内核函数地址的范围里,这些数值会被误认为return address从而打印出错误的调用关系。 
          


一、dump_stack(堆栈转储)作用:主要用于内核调试,打印内核堆栈段信息。

二、使用前便已内核时:使用前,先在内核配置中把kernel debug选上:

make menuconfig:
kernel hacking-->
kernel debug三、arch/x86/kernel/dumpstack.c
void dump_stack(void){
unsigned long bp=0;
unsigned long stack;
#ifdef CONFIG_FRAME_POINTER
if(!bp)
get_bp(bp);
#endif
printk("pid:%d,comm:%20s %s %s %.*s/n",current->pid,current->comm,print_tainted(),init_utsname()->release,(int)strcspn(init_utsname()->version,init_utsname()->version);
show_trace(NULL,NULL&stack,bp);
}

dump_stack不准确的原因分析

   kernel panic后打印的堆栈信息是调用dump_stack函数获得的。而dump_stack的原理是遍历堆栈,把所有可能是内核函数的内容找出来,并打印对应的函数。因为函数调用时会把下一条指令的地址放到堆栈中。所以只要找到这些return address,就可以找到这些return address所在函数,进而打印函数的调用关系。 
         但是dump_stack可能不准确,可能的原因有三: 
         1.所有这些可以找到的函数地址,存在/proc/kallsyms中。它并不包括内核中所有的函数,而只包括内核中stext~etext和sinittext~einittext范围的函数,及模块中的函数。详细可参考scripts/kallsyms.c 
         2.一些函数在编译时进行了优化,把call指令优化为jmp指令,这样在调用时就不会把return address放到堆栈,导致dump_stack时在堆栈中找不到对应的信息。 
         3.堆栈中可能有一些数值,它们不是return address,但是在内核函数地址的范围里,这些数值会被误认为return address从而打印出错误的调用关系。