2011-10-21 33 views
2

我在想,如果从内核(Linux的在这种情况下)你叫ptrace_request与PTRACE_SINGLESTEP在进程上下文(系统调用,缺页等)会发生什么。它会单步执行用户空间指令还是内核空间指令?我意识到,ptrace只能单步执行用户指令,这就是为什么我对这会产生的行为感到好奇。Ptrace从进程上下文中的单步执行内核?

只是提供多一点信息,我试图从一个页面故障处理程序这样做(单步产生故障的指令,但改变PTE地,指令经过)。我想知道这是否甚至有可能,或者如果它需要另一种方法来做到这一点,例如重新安排进程运行等等......

这是因为进程的task_struct(如果被抢占)仍然会指向内核空间处理程序IIRC,因此单步执行ptrace会绕过这一步并执行正确的用户空间指令,或者完全不执行该操作?

回答

1

我不完全理解你的意思,PTRACE_SINGLESTEP总是从内核的用户上下文中调用:当你执行你的系统调用ptrace(PTRACE_SINGLESTEP)时,你将最终在内核上下文中执行该函数,像通常那样运行,并且使您正在执行的进程执行一条指令,而不管您是否从页错误处理程序调用该指令。像往常一样在内陆地区,你将无法单步执行。

我建议你看一看弓/ 86 /内核/ ptrace.c了解如何一步实际工作。单步指令实际上是由内核模拟的,IIRC对此没有硬件支持。

0

要理解回答你的问题,你需要了解英特尔的硬件。

首先我们先从最简单的指令(因为SINGLE_STEP是把Intel的CPU进入单步执行模式,并执行一个结构调查后又回到中断处理程序):

MOVL(EAX),EBX

继Intel的格式,这意味着采取的价值观里面EAX,把它当作一个内存指针,访问内存,得到了4点字节的值,并将其复制到EBX。

这ONE汇编指令 - 当内核VS用户上下文中执行将有不同的行为/含义。

如果在内核中,内核的页表将用于访问内存,并将数据复制到ebx。在用户进程中,用户的页表将被使用(通过MMU硬件),从内存中读取数据并复制到ebx。 eax中的相同值,但CR3寄存器中的值不同(意味着不同的进程上下文),将触发内存的不同部分进行读取。所以在内核中跟踪用户空间程序,真的很荒谬。因为你必须在执行用户指令前后执行上下文切换(涉及整套寄存器存储和恢复操作),这意味着有效地执行4次操作。如你所见,我没有引用任何内核函数API,就像你提到过的那样。首先是总体概念理解。