'?'意味着关于这个堆栈条目的信息可能不可靠。
堆栈输出机制(请参阅dump_trace()function的实现)未能证明它找到的地址是调用堆栈中的有效返回地址。
'?'本身由printk_stack_address()输出。
堆栈条目可能有效或不可用。有时侯可以简单地跳过它。调查相关模块的反汇编以查看在ClearFunctionName+0x88(或则在x86上紧接该位置之前)调用那个函数可能会有所帮助。
关于可靠性
在x86上,当dump_stack()被调用时,实际检测中堆叠arch/x86/kernel/dumpstack.c定义print_context_stack()的功能。瞧瞧它的代码,我会试着在下边解释它。
我假定您的Linux系统中没有DWARF2堆栈解除设备(假如不是OpenSUSE或SLES,很可能不是)。在这些情况下,print_context_stack()或许执行以下操作。
它从保证堆栈位置的地址的地址(代码中的“堆栈”变量)开始。它实际上是dump_stack()中局部变量的地址。
函数重复递增该地址(while(valid_stack_ptr...){...stack++})并检测它指向的内容是否也可以是内核代码中的地址(if(__kernel_text_address(addr))...)。通过这些方法linux使用问号查询字符中标麒麟linux,当这种函数被调用时,它会尝试查找函数的栈上返回地址。
其实linux使用问号查询字符,并不是每位看上去像返回地址的无符号长整型值实际上都是返回地址。所以该函数企图检测它。若果在内核的代码中使用帧表针(假如CONFIG_FRAME_POINTER被设置,则使用%ebp/%rbp寄存器),它们可以用于遍历函数的堆栈帧。函数的返回地址坐落帧表针的正上方(即在%ebp/%rbp+sizeof(unsignedlong)处)。print_context_stack完全检测。
假如存在“堆栈”指向的值为返回地址的堆栈帧,则该值被视为可靠的堆栈条目。ops->address将与reliable==1一起被调用RED HAT LINUX 9.0,它最终将调用printk_stack_address()并将该值作为可靠的调用堆栈条目输出。否则地址将被视为不可靠。不管怎么,它就会输出,而且会显示'?'前缀。[注意]假如帧表针信息不可用(比如默认情况下它是在Debian6中),则因为这个缘由,所有调用堆栈条目都将被标记为不可靠。
具有DWARF2展开支持(但是设置了CONFIG_STACK_UNWIND)的系统是另一回事。