如何判断进程是在内核还是用户空间?

时间:2011-11-14 21:38:32

标签: process kernel daemon space

某些进程,特别是某些守护进程,可以在内核空间或用户空间中运行(有点像用户可以在正常模式或超级用户模式下运行)。有没有一种简单的方法可以找出任何给定进程(守护进程)的内容?

2 个答案:

答案 0 :(得分:1)

通常(在单片内核中,无论如何),进程可以在用户空间和内核空间中运行,具体取决于他们正在做什么。用户代码将在用户空间中运行,直到它需要内核服务,即内核系统调用。然后程序将产生陷阱,该CPU将CPU切换到保护模式,其中内核代码执行系统调用(例如,读取或写入文件)。完成后,内核切换回用户模式,用户应用程序继续运行。在任何时候都是正在运行的用户进程;它只是运行用户代码或内核代码。

修改

至少在Linux上,我认为没有办法判断只有内核的进程是否会掉进用户空间;毕竟,内核可以做任何想做的事情。但是,您可以使用一些启发式方法进行有根据的猜测。例如,pmap将告诉您为进程映射了哪些用户空间内存;没有记忆是一个非常强有力的证据(也许是无可争议的)它是一个核心任务。同样,如果'ps l'中的VSZ字段为0,则表示该任务没有分配用户空间内存。如果你现在只对这个任务是否在内核中感兴趣,那么'ps l'中的WCHAN字段会给你一个提示;如果它不是 - ,它在内核中,如果是 - 那么它可能在用户空间中,但我不确定它是否也意味着它在内核空间中被抢占了。

答案 1 :(得分:0)

有些特定于体系结构的寄存器可以告诉您处于哪种模式:-

a)您可以在调试时使用硬件/软件调试器检查该寄存器的值 e; g:适用于arm的CPSR和适用于x86的CS

代码段描述符的低两位将确定代码正在执行的当前特权级别

b)在代码中,您可以使用宏user_mode(regs),该宏在内部使用 cpsr或cs寄存器。

user_mode(regs)确定寄存器集是否来自用户模式。

例如:在手臂上,使用了 cpsr

#define user_mode(regs) \
    (((regs)->ARM_cpsr & 0xf) == 0)

https://elixir.bootlin.com/linux/v4.5/source/arch/arm/include/asm/ptrace.h#L20

例如:-在x86中,使用 cs

static inline int user_mode(struct pt_regs *regs)
{
#ifdef CONFIG_X86_32
    return ((regs->cs & SEGMENT_RPL_MASK) | (regs->flags & X86_VM_MASK)) >= USER_RPL;
#else
    return !!(regs->cs & 3);
#endif
}

https://elixir.bootlin.com/linux/v4.5/source/arch/x86/include/asm/ptrace.h#L106

对于所有其他架构,请检查下面的链接

https://elixir.bootlin.com/linux/v4.5/ident/user_mode