如何确定保存在堆栈中的值?

我正在做一些试验,希望能够看到系统调用期间保存在堆栈中的内容(用户登陆过程的保存状态)。 根据http://lxr.linux.no/#linux+v2.6.30.1/arch/x86/kernel/entry_32.S,它显示寄存器的各种值被保存在堆栈指针的特定偏移处。 这里是我一直试图用来检查什么是保存在堆栈上的代码(这是在我创build的自定义系统调用):

asm("movl 0x1C(%esp), %ecx"); asm("movl %%ecx, %0" : "=r" (value)); 

其中value是一个无符号long。

截至目前,这个值不是预期的(它显示为ds的用户值保存了一个0)。

我正确访问堆栈指针的偏移量?

另一种可能性是我可以使用debugging器(如GDB)在内核中检查堆栈内容吗? 我没有太多的广泛使用与debugging,我不知道如何debugging内核的代码。 任何帮助深表感谢。

Solutions Collecting From Web of "如何确定保存在堆栈中的值?"

不需要内联汇编。 entry_32.S到系统调用栈的保存状态被作为一个struct pt_regs ,你可以像这样得到一个指针(你需要包含<asm/ptrace.h>和/或<asm/processor.h>直接或间接):

struct pt_regs *regs = task_pt_regs(current);

内联汇编比看起来更棘手。 试图很快涵盖GCC的担忧:

  1. 如果它修改处理器寄存器,则需要将这些寄存器放在clobber列表中。 需要注意的是,clobber列表必须包含您直接更改( 显式读取)或间接( 隐式读取)的所有寄存器。
  2. 为了加强(1),条件操作和数学操作也会改变寄存器,也就是状态标志(zero,carry,overflow等),所以你必须通过在clobber列表中加上“cc”来通知它。
  3. 如果修改不同的(随机读取)内存位置,则添加“内存”
  4. 如果修改输入/输出参数中未提及的内存,请添加volatile关键字;

然后,你的代码变成:

 asm("movl 0x1C(%%esp), %0;" : "=r" (value) : /* no inputs :) */ /* no modified registers */ ); 

输出参数不需要在clobber列表中,因为GCC已经知道它将被改变。

另外,因为所有你想要的是ESP寄存器的值,你可以避免所有的痛苦:

 register int esp asm("esp"); esp += 0x1C; 

它可能无法解决你的问题,但这是一条路。 作为参考,检查这个 , 这个和这个 。

请记住,x86_64代码通常会在寄存器中传递值(因为它有很多),因此堆栈上没有任何东西。 检查gcc中间输出( -S IIRC)并查找组件中的push

我不熟悉调试内核代码,但gdb交互式地检查堆栈更好。