Linux 内核任务的堆栈指针是如何为每个线程确定的?

How is a Linux kernel task's stack pointer determined for each thread?

我正在开发一种有时会劫持应用程序执行的工具,包括在不同的堆栈中工作。

我试图让内核在执行某些系统调用时始终看到应用程序堆栈,以便它会在 /proc/pid/maps 的正确位置打印 [stack] 限定符。

然而,简单地围绕系统调用修改esp似乎是不够的。当我在 "cat /proc/self/stat" 上使用我的工具时,我看到 kstkesp (entry 29 here) 有时具有我想要的值,但有时具有不同的值,对应于我的备用堆栈。

我正在尝试理解:

  1. /proc/self/stat:29中体现的值是如何确定的?
  2. 我可以修改它以便它可靠地具有适当的值吗?
  3. 如果 2 很难回答,您建议我去哪里看一下以了解为什么值间歇性不正确?

看起来它已被定义,例如在 http://lxr.free-electrons.com/source/fs/proc/array.c?v=3.16 的第 409 行给我。

在过去的几年中,有很多关于相关宏 KSTK_ESP 的讨论,例如:https://github.com/davet321/rpi-linux/commit/32effd19f64908551f8eff87e7975435edd16624

http://lists.openwall.net/linux-kernel/2015/01/04/140

根据我收集到的关于间歇性异常的信息,似乎 NMI 或其他中断有时会在内核中命中,然后在这种情况下它无法正确遍历堆栈。