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

Process 如何判断进程是在内核还是在用户空间?,process,kernel,daemon,space,Process,Kernel,Daemon,Space,某些进程,特别是某些守护进程,可以在内核空间或用户空间中运行(有点像用户可以在正常或超级用户模式下运行)。是否有一种简单的方法可以找出它对于任何给定进程(守护进程)是什么?通常(无论如何,在单片内核中),进程可以在用户空间和内核空间中运行,这取决于它们在做什么。用户代码将在用户空间中运行,直到它需要内核服务,即内核系统调用。然后,程序将导致一个陷阱,该陷阱将CPU切换到保护模式,内核代码在该模式下执行系统调用(例如,读取或写入文件)。完成后,内核将切换回用户模式,用户应用程序将继续运行。始终是用

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

通常(无论如何,在单片内核中),进程可以在用户空间和内核空间中运行,这取决于它们在做什么。用户代码将在用户空间中运行,直到它需要内核服务,即内核系统调用。然后,程序将导致一个陷阱,该陷阱将CPU切换到保护模式,内核代码在该模式下执行系统调用(例如,读取或写入文件)。完成后,内核将切换回用户模式,用户应用程序将继续运行。始终是用户进程在运行;它只是运行用户代码或内核代码,视情况而定

编辑


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

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

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

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

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

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

e、 g:在arm中,使用了cpsr

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

e、 g:-在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
}

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


我真的很怀疑。您可以在内核空间中使用HTTP服务器,但它肯定不是在用户空间中运行的服务器。大多数守护进程在用户空间中运行,并在运行内核代码时切换到内核空间,就像应用程序一样。然而,有些守护进程是专门设计为完全在内核空间中运行的(一个随机的例子是kHTTPd,)。显然,pid或所有者本身不足以判断进程是在用户空间还是在内核空间。问题仍然存在:用户(或任何第三方进程)如何判断给定进程(守护进程、线程)是否在内核空间中?显然,我们必须排除这类进程发出的任何内核调用。也许更好的问题是:如何判断内存中的代码块是在用户空间还是在内核空间?ps命令具有进程标志4“已使用的超级用户权限”(例如,“ps-p pid-o f”,其中pid是感兴趣的进程ID);当它返回4(或5,因为另一个进程标志的值为1)时,是否意味着该进程在过去的某个时间点在内核空间中运行?这不是我想要的,但这将是一个开始。这里有另一个解决方案元素:内核线程不需要用户空间内存页目录,因此它们将空指针值存储在其“任务结构”进程描述符的“mm”字段中。接下来的问题是:如何向内核询问进程的task_struct.mm值?我现在看到(linux/sched.h)这两个ps进程标志确实来自task_struct->flags(特别是PF_FORKNOEXEC 0x00000040'分叉但未执行',PF_SUPERPRIV 0x0000100'使用超级用户权限')。这组相同的标志包括PF_KTHREAD 0x00200000“我是内核线程”。可惜ps没有报告后一个标志。