/proc 文件

用途

包含有关系统中的进程和线程的状态信息。

语法

   #include <sys/procfs.h>

描述

/proc 文件系统提供对系统中每个活动进程和线程的状态的访问权。 /proc 文件系统中每个条目的名称都是对应于进程标识的十进制数字。 这些条目是子目录,且每个条目的所有者由进程的用户标识确定。 每个子目录中包含的其他文件提供了对进程状态的访问权。 除非另有指定,否则术语 /proc 文件 是指根植于 /proc的层次结构中的非目录文件。 每个文件的所有者都由进程的用户标识确定。

各种 /proc 目录,文件和字段名称都包含术语 勒夫普 (轻量过程)。 此术语指的是内核线程。 /proc 文件不引用用户空间 pthreads。 虽然操作系统不使用术语 lwp 来描述其线程,但在 /proc 文件系统中使用此术语是为了与其他 UNIX 操作系统兼容。

下面的标准子例程接口用于访问 /proc 文件:

  • 子例程
  • 关闭 子例程
  • 子例程
  • 子例程

大多数文件描述了进程状态,并且旨在为只读。 控制 (控制) 和 勒夫茨特尔 (线程控制) 文件允许对进程状态进行操作,并且只能打开以进行写入。 作为 (地址空间) 文件包含正在运行的进程的图像,并且可以打开该文件进行读写。 写打开允许进程控制,只读打开允许检查,但不允许进程控制。 因此,如果某个进程的任何关联 /proc 文件分别打开以进行读或写操作,那么该进程将被描述为打开以进行读或写操作。

一般情况下,多个进程可以同时打开同一个 /proc 文件。 互斥打开是为了允许进程控制,而不允许另一个进程同时尝试打开该文件。 如果进程在 子例程中指定 O_EXCL 标志时成功打开目标进程中的任何 /proc 文件以进行写入 ( 作为控制 文件,或任何内核线程的 勒夫茨特尔 文件) ,那么它可以获得目标进程的互斥控制。 如果目标进程已打开以进行写入 (即,如果 控制作为勒夫茨特尔 文件已打开以进行写入) ,那么 子例程的此类调用将失败。 可以存在 子例程的多个并发只读实例; 在 子例程上忽略 O_EXCL 标志以进行读取。 由控制进程写入的第一个打开项应使用 O_EXCL 标志。 尝试控制同一目标进程的多个进程通常会导致错误。

通过调用 寻求 子例程将 作为 文件定位在感兴趣的虚拟地址,然后调用 子例程,可以将数据从被跟踪进程的地址空间中的任何位置传输或传输到被跟踪进程的任何位置。 扩展至未映射区域的 I/O 请求在边界处被截断。 从未映射的虚拟地址开始的 请求在 错误号 设置为 EFAULT时失败。

通过其他文件提供信息和控制操作。 <sys/procfs.h> 文件包含与这些文件一起使用的数据结构和消息格式的定义。 这些定义中的某些定义使用标志集。 集合类型 pr_sigset_t弗利采特sysset_t 分别对应于信号枚举,故障枚举和系统调用枚举。 这些枚举在 <sys/procfs.h> 文件中定义。 pr_sigset_t弗利采特 类型足够大,可以容纳其自己的枚举的标志。 虽然它们大小不同,但它们具有共同的结构,并且可以由以下宏进行操作:
   prfillset(&set);            /* turn on all flags in set */
   premptyset(&set);           /* turn off all flags in set */
   praddset(&set, flag);       /* turn on the specified flag */
   prdelset(&set, flag);       /* turn off the specified flag */
   r = prismember(&set, flag); /* != 0 if flag is turned on */

必须先使用 普尔菲利塞前缀集 宏来初始化 pr_sigset_t弗利采特 类型,然后才能在任何其他操作中使用该宏。 参数必须是对应于适当集合的枚举的成员。

sysset_t 集类型具有不同的格式,宏集以及可变长度结构,以适应不同数量的可用系统调用。 您可以通过读取 系统发送 文件来确定系统调用的总数,系统调用的名称以及每个单独调用的数目。 然后,您可以为适当大小的 sysset_t 结构分配内存, 通过确保 pr_sysset 阵列每 64 个系统调用号都需要一个元素, 初始化其 pr_size 字段,然后使用以下宏来处理系统调用集:
int      num;                 /* Specifies the systemcall's number from sysent */
uint64_t sysnum;              /* Specifies the number of elements in pr_set array */
uint64_t syssize;             /* Allocates the size */
sysset_t *set;                /* Specifies the pointer to sysset_t */
sysnum = (num - 1)/64 + 1;
syssize = (sysnum + 1) * sizeof(uint64_t);
set = (sysset_t *)malloc(syssize);
set->pr_size = sysnum;
prfillsysset(set)          /* set all syscalls in the sysset */
premptysysset(set)         /* clear all syscalls in the sysset */
praddsysset(set, num)      /* set specified syscall in the sysset */
prdelsysset(set, num)      /* clear specified syscall in the sysset */
prissyssetmember(set, num) /* !=0 if specified syscall is set */

有关系统调用的更多信息,请参阅 系统发送 文件的描述。

每个活动进程至少包含一个内核线程。 每个内核线程都表示一个由操作系统独立调度的执行流。 进程中的所有内核线程都共享地址空间以及许多其他属性。 通过使用 控制勒夫茨特尔 文件,您可以根据操作对进程中的个别内核线程进行操作或同时对所有内核线程进行操作。

当一个进程有多个内核线程时,系统会为某些进程状态文件和控制操作选择一个代表性线程。 仅当进程的所有线程都已停止时,才会停止代表性线程。 仅当所有线程都已停止时,代表线程才能在 感兴趣的事件 上停止,或者仅当不存在其他相关事件时,代表线程才能由 PR_REQUESTED 停止。

只要所有线程都在感兴趣的事件上停止或处于 PR_SUSPENDED stop 中,并且 PCRUN 操作数未应用于任何线程,那么代表线程将保持固定。

当应用于进程控制文件 (控制) 时,影响内核线程的每个 /proc 控制操作都使用相同的算法来选择要对哪个内核线程执行操作。 通过同步停止 (请参阅 PCSET) ,此行为使应用程序能够仅使用进程级别状态和控制文件来控制多线程进程。 要进行更多控制,请使用特定于线程的 勒夫茨特尔 文件。

/proc 文件系统可以同时由 32 位和 64 位控制进程使用,以获取有关 32 位和 64 位目标进程的信息。 /proc 文件向所有观察器提供 64 位启用的方式不变文件。 控制过程的方式不影响 /proc 数据的格式。 数据将以相同的格式返回到 32 位和 64 位控制进程。 /proc 文件中的地址以及适用的长度和偏移量字段长度为 8 个字节。

目录结构

在顶级, /proc 目录包含条目,其中每个条目都对系统中的现有进程进行命名。 此目录中的条目名称是进程标识 (pid) 号。 这些条目是目录。 除非另有说明,否则下面描述的文件是只读的。 此外,如果某个进程成为 僵尸 (该进程已由其父代通过 退出 调用终止,但未由 调用暂挂) ,那么其大多数关联 /proc 文件将从目录结构中消失。 通常,稍后在进程终止前尝试打开或读取或写入已打开的文件时,会产生 ENOENT 消息。 记录异常。

/proc 文件包含用于显示系统中进程和线程的状态的数据。 在系统运行时,此状态不断变化。 为了减轻由于读取 /proc 个文件而导致的系统性能负载, /proc 文件系统在收集这些文件的数据时不会停止系统活动。 /proc 文件的单次读取通常会返回进程或线程状态的一致且相当准确的表示。 但是,由于在进程或线程运行时状态会更改,因此多次读取 /proc 文件可能会返回显示不同数据的表示,并因此显示为彼此不一致。

原子 表示法是进程或线程在单个和离散时间点的表示法。 如果您需要进程或线程状态的原子快照,请先停止该进程和线程,然后再读取该状态。 对于正在运行的进程的 /proc 文件的连续读取,不保证数据是原子快照。 此外,对于应用于 作为 (地址空间) 文件的任何 I/O ,也不保证表示为原子的表示。 任何进程地址空间的内容都可能同时由该进程的线程或系统中的任何其他进程修改。
注: 使用了多个结构定义来描述 /proc 文件。 /proc 文件可能包含除此处提供的定义以外的其他信息。 在操作系统的未来发行版中,这些结构可能会通过在结构的末尾添加字段而增长。

/proc/pid 文件结构

/proc/ 目录中包含 (但不限于) 以下条目:

as
包含该进程的地址空间图像。 可以打开 作为 文件以进行读和写操作。 寻求 子例程用于将该文件定位在感兴趣的虚拟地址。 然后,您可以分别使用 子例程和 子例程来查看和修改地址空间。
ctl
这是一个仅写文件,结构化消息将写入该文件,指示系统更改进程状态的某些方面或以某种方式控制其行为。 搜索偏移量在写入此文件时不相关,请参阅控制消息类型以获取更多信息。 个别线程也具有关联的 勒夫茨特尔 文件。 可以将控制消息写入进程的 控制 文件,也可以写入具有特定于操作的效果的特定 勒夫茨特尔 文件,如所述。 控制消息的效果立即反映在通过相应的状态和信息文件可见的进程状态中。
状态
包含有关进程及其代表线程之一的状态信息。 该文件将格式化为包含以下成员的 struct pstatus 类型:
uint32_t pr_flag;                   /* process flags from proc struct p_flag */
uint32_t pr_flag2;                  /* process flags from proc struct p_flag2 */
uint32_t pr_flags;                  /* /proc flags */
uint32_t pr_nlwp;                   /* number of threads in the process */
char     pr_stat;                   /* process state from proc p_stat */
char     pr_dmodel;                 /* data model for the process */
char     pr__pad1[6];               /* reserved for future use */
pr_sigset_t pr_sigpend;             /* set of process pending signals */
prptr64_t pr_brkbase;               /* address of the process heap */
uint64_t pr_brksize;                /* size of the process heap, in bytes */
prptr64_t pr_stkbase;               /* address of the process stack */
uint64_t pr_stksize;                /* size of the process stack, in bytes */
pid64_t  pr_pid;                    /* process id */
pid64_t  pr_ppid;                   /* parent process id */
pid64_t  pr_pgid;                   /* process group id */
pid64_t  pr_sid;                    /* session id */
struct pr_timestruc64_t pr_utime;   /* process user cpu time */
struct pr_timestruc64_t pr_stime;   /* process system cpu time */
struct pr_timestruc64_t pr_cutime;  /* sum of children's user times */
struct pr_timestruc64_t pr_cstime;  /* sum of children's system times */
pr_sigset_t pr_sigtrace;            /* mask of traced signals */
fltset_t pr_flttrace;               /* mask of traced hardware faults */
uint32_t pr_sysentry_offset;        /* offset into pstatus file of sysset_t
                                     * identifying system calls traced on
                                     * entry.  If 0, then no entry syscalls
                                     * are being traced. */
uint32_t pr_sysexit_offset;         /* offset into pstatus file of sysset_t
                                     * identifying system calls traced on
                                     * exit.  If 0, then no exit syscalls
                                     * are being traced. */
uint64_t pr__pad[8];                /* reserved for future use */
lwpstatus_t pr_lwp;                 /* "representative" thread status */

下面对 状态 文件的成员进行了描述:

PR标志
指定持有这些标志的位掩码:
PR_ISSYS
进程是内核进程 (请参阅 PCSTOP)
PR_FORK
进程已设置其派生时继承标志 (请参阅 PCSET)
PR_RLC
进程已设置其 "上次关闭时运行" 标志 (请参阅 PCSET)
PR_KLC
进程已设置其 "上次关闭时终止" 标志 (请参阅 PCSET)
PR_ASYNC
进程已设置其异步停止标志 (请参阅 PCSET)
PR_PTRACE
进程由 跟踪 子例程控制
pr_nlwp
指定进程中的总线程数
Pr_brkbase
指定进程堆的虚拟地址。
pr_brksize
指定进程堆的大小 (以字节为单位)
注:Pr_brkbasepr_brksize 的和构成的地址是进程 (请参阅 布尔克 子例程)。
pr_stkbase
指定进程堆栈的虚拟地址。
pr_stksize
指定进程堆栈的大小 (以字节为单位)
注: 每个线程都在单独的堆栈上运行。 必要时,操作系统会增大进程堆栈。
pr_pid
指定进程标识
Pr_ppid
指定父进程标识
Pr_pgid
指定进程组标识
pr_sid
指定该进程的会话标识
pr_utime
指定进程所耗用的用户 CPU 时间
Pr_stime
指定进程所耗用的系统 CPU 进程时间
pr_cutime
指定进程子代耗用的累积用户 CPU 时间,以秒和纳秒为单位表示
pr_cstime
指定进程子代耗用的累积系统 CPU 时间 (以秒和纳秒为单位)
pr_sigtrace
指定正在跟踪的信号的集合 (请参阅 PCSTRACE 信号)
pr_flttrace
指定要跟踪的硬件故障的集合 (请参阅 PCSFAULT 信号)
pr_sysentry_偏移量
如果非零,那么在 状态 文件中包含对系统调用条目上跟踪的 sysset_t 组系统调用的偏移量 (请参阅 PCSENTRY 信号)。 如果进程的系统调用跟踪未处于活动状态,那么此标志为零。
pr_sysexit_偏移量
如果为非零,那么在 状态 文件中包含对系统调用出口跟踪的 sysset_t 系统调用集的偏移量 (请参阅 PCSEXIT 信号)。 如果进程的系统调用跟踪未处于活动状态,那么此字段为零。
Pr_lwp
如果该进程不是 zombie ,那么包含用于描述代表性线程的 lwpstatus_t 结构。 此结构的内容的含义与从 Lwpstatus 文件中读取的内容的含义相同。
psinfo
包含有关 ps 命令所需要的进程的信息。 如果该进程包含多个线程,那么将使用代表性线程来派生 lwpsinfo 信息。 该文件将格式化为 struct psinfo 类型,并包含以下成员:
uint32_t pr_flag;                   /* process flags from proc struct p_flag */
uint32_t pr_flag2;                  /* process flags from proc struct p_flag2 */
uint32_t pr_nlwp;                   /* number of threads in process */
uid_t    pr_uid;                    /* real user id */
uid_t    pr_euid;                   /* effective user id */
gid_t    pr_gid;                    /* real group id */
gid_t    pr_egid;                   /* effective group id */
uint32_t pr_argc;                   /* initial argument count */
pid64_t  pr_pid;                    /* unique process id */
pid64_t  pr_ppid;                   /* process id of parent */
pid64_t  pr_pgid;                   /* pid of process group leader */
pid64_t  pr_sid;                    /* session id */
dev64_t  pr_ttydev;                 /* controlling tty device */
prptr64_t   pr_addr;                /* internal address of proc struct */
uint64_t pr_size;                   /* size of process image in KB (1024) units */
uint64_t pr_rssize;                 /* resident set size in KB (1024) units */
struct   pr_timestruc64_t pr_start; /* process start time, time since epoch */
struct   pr_timestruc64_t pr_time;  /* usr+sys cpu time for this process */
prptr64_t   pr_argv;                /* address of initial argument vector in
                                       user process */
prptr64_t   pr_envp;                /* address of initial environment vector
                                       in user process */
char     pr_fname[PRFNSZ];          /* last component of exec()ed pathname*/
char     pr_psargs[PRARGSZ];        /* initial characters of arg list */
uint64_t pr__pad[8];                /* reserved for future use */
struct   lwpsinfo pr_lwp;           /* "representative" thread info */
注: psinfo 文件中的某些条目 (例如 pr_flagpr_flag2Pr_addr) 引用内部内核数据结构,并且可能不会在不同版本的操作系统中保留它们的含义。 它们对程序没有任何意义,并且仅对于了解实施详细信息的用户进行手动解释时才有用。

在进程变为 zombie 后,可以访问 psinfo 文件。

Pr_lwp 标志描述所选的代表性线程。 如果进程是 zombie ,那么 pr_nlwppr_lwp.pr_lwpid 标志为零,并且未定义 pr_lwp 的其他字段。

map
包含有关进程的虚拟地址映射的信息。 该文件包含 普拉普图 结构的数组,其中每个结构都描述所跟踪进程的地址空间中的连续虚拟地址区域。
注: 地图 文件可能仅包含进程的虚拟地址区域的条目,这些虚拟地址区域包含装入到进程中的对象。
普拉普图 结构中包含以下成员:
uint64_t pr_size;                /* size of mapping in bytes */
prptr64_t pr_vaddr;              /* virtual address base */
char     pr_mapname[PRMAPSZ];    /* name in the /proc/pid/object object */
uint64_t pr_off;                 /* offset to the mapped object, if any */
uint32_t pr_mflags;              /* protection and attribute flags */
uint32_t pr_pathoff;             /* if map indicates the entry for a loaded object,
                                  * offset points to a null-terminated path name followed
                                  * by a null-terminated member name.
                                  * If the offset is mapped to a file and it is not an 
                                  * archive file, the member name is null.
                                  * The offset is 0 if map entry is
                                  * not applicable for a loaded object. */
int32_t pr_shmid;                /* shared memory ID for the MA_SHM or
                                  * MA_RTSHM region.
                                  * <0 indicates that teh shared memory ID is not 
                                  * available. */
dev64_t pr_dev;                  /* the dev_t data structure for the MA_FILEMAP file.
                                  * -1 indicates that the dev_t is not available 
                                  * -2 indicates that the file is on remote filesystem,
                                  * -3 indicates that the file is in a WPAR. */                                                                     
ino64_t pr_ino;                  /* The inode datastructure for the MA_FILEMAP file.
                                  * -1 indicates that the ino_t data structure is not 
                                  * available */
vmid64_t pr_vsid;                /* virtual segment ID for the first segment
                                  * in the region. */

这些成员如下所述:

pr_vaddr
指定所跟踪进程中的映射的虚拟地址
pr_size
指定所跟踪进程中的映射大小
pr_mapname
如果不是空字符串,那么将包含驻留在 对象 目录中的文件的名称,并包含虚拟地址所映射到的对象的文件描述符。 该文件是使用 子例程打开的。
Pr_off
包含虚拟地址所映射到的映射对象 (如果有) 中的偏移量
Pr_pathoff
如果非零,那么在 地图 文件中包含指向已装入对象的路径名和归档成员名的偏移量
PR_MFLAGS
指定保护的位掩码以及以下属性标志:
MA_MAINEXEC
指示映射应用于进程中的主可执行文件。
MA_BREAK
指示映射适用于该过程中的程序数据和堆范围。
MA_STACK
指示映射将应用于过程中的堆栈范围。
MA_MMAP
指示映射将应用于通过使用 mmap 子例程映射到进程的对象。
MA_RTSHM
  • 指示映射将应用于由 Shm_open 子例程创建的 POSIX 实时对象。
  • 这些对象通过使用 mmap 子例程映射到进程。
MA_SHM
指示映射将应用于通过使用 什马特 子例程映射到进程的对象。
MA_FILEMAP
指示映射适用于使用 mmap 子例程或 shmat 子例程映射到进程的文件对象。
MA_WORK
指示映射应用于由装入程序或其他内核子系统映射到进程的内存。
MA_RMMAP
指示映射适用于通过使用 rmmap_create 子例程映射到进程中的内存或 I/O 区域。
MA_KERNTEXT
指示映射将应用于映射到进程的内核内存。
MA_PS4K
指示映射受 4 KB 的物理内存块支持。
MA_PS64K
指示 64 KB 物理内存块所支持的映射。
MA_PS16M
指示受 16 MB 物理内存块支持的映射。
MA_PS16G
指示受 16 GB 物理内存块支持的映射。
MA_READ
指示所跟踪的进程可读取映射。
MA_WRITE
指示所跟踪的进程可写映射。
MA_EXEC
指示所跟踪的进程可执行映射。
MA_共享
指示映射更改由已映射的对象共享。
Pr_shmid
对于 MA_SHM 映射,它包含该映射的 System V 共享内存标识。 使用 ipcs -m 命令可显示共享内存标识。
Pr_dev
对于 MA_FILEMAP 映射,包含所映射文件的设备标识编号。
pr_ino
对于 MA_FILEMAP 映射,在 pr_dev 字段中包含相对于设备标识的映射文件的索引节点号。
pr_vsid
包含映射中的第一个虚拟内存管理器段标识。

由于读取,写入,执行和共享属性的变化,具有相同底层映射对象的地址空间的连续区域可能会显示为多个映射。 底层已映射对象不会在单个映射的范围内更改。 如果在与底层映射对象中的有效页面不对应的虚拟地址处应用标记为 MA_SHARED 的映射,那么对该映射的 I/O 操作将失败。 对专用映射的读写操作始终成功。 对未映射地址的读写操作总是失败。

克雷德
包含与该过程关联的凭证的描述。 该文件将格式化为 斯特鲁特-普克雷德 类型,并包含以下成员:
uid_t    pr_euid;                /* effective user id */
uid_t    pr_ruid;                /* real user id */
uid_t    pr_suid;                /* saved user id (from exec) */
gid_t    pr_egid;                /* effective group id */
gid_t    pr_rgid;                /* real group id */
gid_t    pr_sgid;                /* saved group id (from exec) */
uint32_t pr_ngroups;             /* number of supplementary groups */
gid_t    pr_groups[1];           /* array of supplementary groups */
系统发送
包含有关可用于进程的系统调用的信息。 可以使用该文件来查找要跟踪的特定系统调用的编号。 它可用于查找与 Lwpstatus 文件中返回的系统调用号关联的系统调用的名称。

该文件由一个头部分组成,后跟一个条目数组,每个条目都对应于提供给进程的系统调用。 每个数组条目都包含系统调用号以及 系统发送 文件中到该系统调用以 null 结束的名称的偏移量。

系统发送 文件由以下属性进行特征描述:

  • 系统调用名称是已导出的系统调用的实际内核名称。
  • 数组中的条目不具有任何特定顺序。
  • 在系统呼叫号码中可能存在间隔。
  • 不同的进程可能有不同的系统调用名称和编号,特别是在 32 位进程和 64 位进程之间。 请勿假定相同的名称或数字跨越不同的进程。
  • 在操作系统运行期间,系统调用的集合可能发生更改。 您可以在操作系统正在运行时添加系统调用。
  • 系统调用的名称和编号可能在不同发行版中或在服务应用于系统时发生更改。
cwd
提供对进程的当前工作目录的访问权的链接。 任何进程都可以通过此链接访问进程的当前工作目录,前提是它具有必需的许可权。
fd
包含进程的所有打开文件描述符的文件。 每个条目都是与进程中打开的文件描述符相对应的十进制数字。 如果 enty 指的是常规文件,那么可以使用常规文件语义打开它。 为了确保 controlling 进程无法获得更大的访问权,在受控进程中除了它自己的读/写打开方式之外,没有其他文件访问方式。 目录将显示为链接。 尝试打开任何其他类型的条目都将失败 (因此列出时将显示 0 个许可权)。
对象
一个包含只读文件的目录,这些文件的名称显示在 地图 文件的条目中,对应于映射到目标进程的地址空间中的对象。 打开此类文件将生成与特定地址空间区域相关联的映射文件的描述符。 名称 a.out 也作为与正在运行的进程的文本相关联的可执行文件的同义词出现在目录中。

对象目录使控制进程能够访问对象文件和任何共享库 (以及因此获得的符号表) ,而不需要该进程首先获取这些文件的特定路径名。

root
一个链接,用于提供对进程的当前根目录的访问权。 任何进程都可以通过此链接访问该进程的当前根目录,前提是该进程 (正在尝试访问根目录) 具有必需的许可权。
mmap
这是一个包含 stat64x 结构数组的文件。 每个结构都描述了与进程所拥有的内存映射区域相关联的文件的相关信息。
lwp
一个包含条目的目录,每个条目都对包含进程中的内核线程进行命名。 此目录中的条目名称是线程标识 (tid) 号。 这些条目是包含以下描述的其他文件的目录。

/proc/pid/lwp/tid 结构

目录 /proc//lwp/标识 中包含以下条目:

勒夫茨特尔
这是一个只写的控制文件。 写入此文件的消息仅影响关联的线程,而不会影响整个进程 (如果适用)。
Lwpstatus
包含特定于线程的状态信息。 此信息也会出现在进程的 状态 文件中,以表示它的代表线程。 该文件将格式化为 结构 lwpstatus ,并包含以下成员:
uint64_t  pr_lwpid;                 /* specific thread id */
uint32_t pr_flags;                  /* thread status flags */
char     pr_state;                  /* thread state - from thread.h t_state */
uint16_t pr_cursig;                 /* current signal */
uint16_t pr_why;                    /* reason for stop (if stopped) */
uint16_t pr_what;                   /* more detailed reason */
uint32_t pr_policy;                 /* scheduling policy */
char     pr_clname[PRCLSZ];         /* printable character representing pr_policy */
pr_sigset_t pr_lwppend;             /* set of signals pending to the thread */
pr_sigset_t pr_lwphold;             /* set of signals blocked by the thread */
pr_siginfo64_t pr_info;             /* info associated with signal or fault */
pr_stack64_t pr_altstack;           /* alternate signal stack info */
struct pr_sigaction64 pr_action;    /* signal action for current signal */
uint16_t pr_syscall;                /* system call number (if in syscall) */
uint16_t pr_nsysarg;                /* number of arguments to this syscall */
uint64_t pr_sysarg[PRSYSARGS];      /* arguments to this syscall */
prgregset_t pr_reg;                 /* general and special registers */
prfpregset_t pr_fpreg;              /* floating point registers */
pfamily_t pr_family;                /* hardware platform specific information */

下面对 Lwpstatus 文件的成员进行了描述:

PR标志
指定持有这些标志的位掩码:
Pr_STOPPED
指示该线程已停止
PR_ISTOP
指示线程在感兴趣的事件时停止 (请参阅 PCSTOP 信号)
PR_DSTOP
指示线程具有有效的 stop 伪指令 (请参阅 PCSTOP 信号)
已入睡
线程在系统调用中处于可中断休眠状态
PR_无注册
没有为线程提供任何注册状态
pr_why pr_why
提供了线程停止的原因。 以下是 pr_why 成员的可能的值:
公关请求
显示线程已停止以响应 stop 伪指令,这通常是因为 PCSTOP 信号已应用,或者另一个线程已在相关事件上停止,并且没有为进程设置异步停止标志 (请参阅 PCSET 信号)。 在此情况下, Pr_h哪些内容 成员未使用。
已发出信号
显示线程在接收到信号时停止 (请参阅 PCSTRACE 信号)。 Pr_h哪些内容 信号保存导致停止的信号号 (对于新停止的线程,将对 pr_cursig 成员提供相同的值)。
PR_已故障
显示线程在发生硬件故障时已停止 (请参阅 PCSFAULT 信号)。 Pr_h哪些内容 成员包含导致该停止的故障号。
PR_SYSENTRY
显示对系统调用的入口的停止 (请参阅 PCSENTRY 信号)。 Pr_h哪些内容 成员包含系统调用号。
PR_SYSEXIT
显示从系统调用退出时的停止 (请参阅 PCSEXIT 信号)。 Pr_h哪些内容 中包含系统呼叫号码。
PR_工作控制
显示由于作业控制停止信号的缺省操作,线程已停止 (请参阅 签名 子例程)。 Pr_h哪些内容 成员包含正在停止的信号号。
Pr_lwpid
对特定线程 I/O 进行命名
pr_cursig
对当前信号进行命名,这是要传递到线程的下一个信号。 当线程被 已发出信号PR_已故障 信号停止时, pr_info 成员将包含与特定信号或故障相关的其他信息。 pr_info 成员中包含的数据量取决于停止类型,以及在建立信号处理程序时应用程序是否指定了 SA_SIGINFO 标志。 对于 PR_已故障 ,如果未指定 SA_SIGINFO 标志,那么停止和停止 已发出信号 ,那么只有 si_signo , si_code 和 si_addr pr_info 字段包含数据。 对于 已发出信号 ,如果指定了 SA_SIGINFO 标志,那么其他 pr_info 字段也会包含数据。
pr_action
包含有关当前信号的信号操作信息。 如果 pr_cursig 成员为零,那么未定义此成员。 请参阅 签名 子例程。
pr_lwppend
标识为线程暂挂的任何同步生成的或线程导向的信号。 它不包括在进程级别暂挂的信号。
pr_替代堆栈
包含该线程的备用信号堆栈信息。 请参阅 锡加尔特斯塔克 子例程。
pr_syscall
指定线程正在执行的系统调用 (如果有的话) 的数目。 当且仅当线程在 PR_SYSENTRYPR_SYSEXIT上停止时,它才为非零值。

如果 pr_syscall 成员为非零值,那么 pr_nsysarg 成员是系统调用的自变量数,并且 Pr_sysarg 数组包含这些自变量。 pr_nsysarg 成员始终设置为 8 (系统调用参数的最大数目)。 Pr_sysarg 成员始终包含八个参数。

pr_clname
包含该线程的调度类的名称
pr_reg
包含线程常规寄存器和专用寄存器的结构。 此结构的大小和字段名称是机器相关的。 请参阅 <sys/m_procfs.h> 头文件以获取特定机器的此结构的描述。 如果线程未停止,那么未定义此结构的内容。
pr_fpreg
包含线程浮点寄存器的结构。 此结构的大小和字段名称是机器相关的。 如果线程未停止,那么未定义此结构的内容。
pr_家族
包含有关线程的特定于机器的信息。 此字段的使用在不同体系结构中不可移植。 pr_family 结构包含扩展上下文偏移量字段和大小字段,如果非零,那么这些字段指示线程的扩展机器上下文信息的可用性。 在指定偏移量和大小处对 状态Lwpstatus 文件进行后续读取将检索对应于 普雷克斯特集 结构的扩展上下文信息。 或者,可将整个 Lwpstatus 文件读取并格式化为 结构 lwpstatusx,其中包含 普雷克斯特集 扩展名。 pr_family 扩展上下文偏移量和大小成员 (如果不为零) 指示 lwpstatusx 结构的 普雷克斯特集 成员是否有效。
lwpsinfo
包含有关 ps 命令所需要的线程的信息。 此信息也存在于它的代表线程的进程的 psinfo 文件中 (如果它有的话)。 该文件将格式化为包含以下成员的 struct lwpsinfo 类型:
uint64_t  pr_lwpid;              /* thread id */
prptr64_t pr_addr;               /* internal address of thread */
prptr64_t pr_wchan;              /* wait addr for sleeping thread */
uint32_t pr_flag;                /* thread flags */
uchar_t  pr_wtype;               /* type of thread wait */
uchar_t  pr_state;               /* numeric scheduling state */
char     pr_sname;               /* printable character representing pr_state */
uchar_t  pr_nice;                /* nice for cpu usage */
int      pr_pri;                 /* priority, high value = high priority*/
uint32_t pr_policy;              /* scheduling policy */
char     pr_clname[PRCLSZ];      /* printable character representing pr_policy */
cpu_t    pr_onpro;               /* processor on which thread last ran */
cpu_t    pr_bindpro;             /* processor to which thread is bound */

lwpsinfo 文件中的某些条目 (例如 pr_flagPr_addrpr_statepr_wtypePr_wchan) 引用内部内核数据结构,并且不应期望在不同版本的操作系统中保留它们的含义。 它们对程序没有任何意义,并且仅对于了解实施详细信息的用户进行手动解释时才有用。

控制消息

进程状态更改通过写入进程的 控制 文件或写入单个线程的 勒夫茨特尔 文件中的消息来实现。 所有控制消息都由 国际 操作码组成,该操作码标识特定操作,后跟包含操作数 (如果有) 的其他数据。 多个控制消息可以在单个 子例程中组合到一个控制文件中,但不允许部分写入。 每个控制消息 (操作码加操作数) 都必须完整地显示在 子例程中,而不是通过几个系统调用来显示。

以下是允许的控制消息:
注: 将消息写入到已退出的进程或线程的控制文件中,从而导致错误 ENOENT
PCSTOP , PCDSTOP 和 PCWSTOP
当应用于过程控制文件时,
  • PCSTOP 指示所有线程停止,并等待这些线程停止;
  • PCDSTOP 指示所有线程停止,而不等待它们停止;
  • PCWSTOP 只会等待所有线程停止。

当应用于线程控制文件时,

  • PCSTOP 指示特定线程停止并等待到其停止为止;
  • PCDSTOP 指示特定线程停止,而不等待该线程停止;
  • PCWSTOP 只需等待线程停止即可。

当应用于线程控制文件时, PCSTOPPCWSTOP 在线程因感兴趣的事件而停止时完成,并在线程已停止时立即完成。

当应用于进程控制文件时, PCSTOPPCWSTOP 将在每个线程在感兴趣的事件上停止时完成。

感兴趣的事件PR_REQUESTED 停止或在进程的跟踪标志中指定的停止 (由 PCSTRACEPCSFAULTPCSENTRYPCSEXIT设置)。 PR_JOBCONTROLPR_SUSPENDED 站不是感兴趣的事件。 (线程可能由于停止信号而停止两次; 如果线程设置为运行而未清除信号,那么首先显示 已发出信号 (如果跟踪了该信号) ,然后再次显示 PR_JOBCONTROL 。) 如果将 PCSTOPPCDSTOP 应用于已停止但并非由于相关事件而停止的线程,那么当线程由竞争机制重新启动时, stop 伪指令将生效; 此时,线程会在执行任何用户级别代码之前进入 PR_REQUESTED 停止。

这是控制消息的 操作,阻塞信号是可中断的,例如,可以设置 警报 子例程以避免等待某个进程或线程,该进程或线程可能在感兴趣的事件上永不停止。 如果 PCSTOP 被中断,那么即使 子例程返回错误,线程停止伪指令仍然有效。

内核进程 (由 PR_ISSYS 标志指示) 永远不会在用户级别执行,并且无法停止。 它没有用户级别地址空间,无法通过 /proc 文件系统查看。 将 PCSTOPPCDSTOPPCWSTOP 应用到系统进程或其任何线程会导致错误 EbUSY

PCRUN
在线程停止后再次执行该线程。 操作数是一组标志,包含在 国际 操作数中,用于描述可选的其他操作。

下面描述了 PCRUN 允许使用的标志:

PRCSIG
清除当前信号 (如果有)。 请参阅 PCSSIG
PRC故障
清除当前故障 (如果有)。 请参阅 PCCFAULT
PRSTEP
指示该线程执行单台机器指令。 在指令完成时,会发生跟踪陷阱。 如果正在跟踪 FLTTRACE ,那么线程将停止,否则将发送 SIGTRAP。 如果正在跟踪且未挂起 SIGTRAP ,那么线程将停止。 当线程在感兴趣的事件上停止时,单步骤伪指令将被取消,即使在执行指令之前发生停止也是如此。
PRSABORT
指示线程异常终止系统调用的执行。 请参阅 PCSENTRYPCSEXIT。 仅当线程处于 PR_SYSENTRY 停止状态或标记为 已入睡时,它才有意义。
停止发布
指示该线程在恢复执行之后尽快再次停止。 请参阅 PCSTOP。 尤其是,如果线程在 已发出信号PR_已故障上停止,那么下一个停止会显示 PR_REQUESTED,没有其他停止干预,并且线程不会执行任何用户级别的代码。

当应用于线程控制文件时, PCRUN 会使特定线程可运行。 如果特定线程未在相关事件上停止,那么该操作将失败并返回错误 EbUSY

当应用于进程控制文件时,将为该操作选择代表性线程,如 /proc//状态 文件所述。 如果在感兴趣的事件上未停止代表线程,那么该操作将失败并返回错误 EbUSY 。 如果请求了 PRSTEPPRSTOP ,那么 PCRUN 会使代表性线程可运行。 否则,所选线程将标记为 PR_REQUESTED。 因此,如果所有线程都处于 PR_REQUESTED 停止状态,那么它们都将变为可运行。

一旦 PCRUN 使线程可运行,它就不再在感兴趣的事件上停止,即使它由于竞争机制而保持停止也是如此。

PC追踪
定义要在该过程中跟踪的一组信号。 在收到其中一个信号后,线程将停止。 该信号集是使用控制消息中包含的操作数 pr_sigset_t 定义的。 无法跟踪 SIGKILL 的接收。 如果指定 SIGKILL,那么线程将忽略它。

如果将包含在线程的挂起信号集中的信号发送到该线程,那么不会接收到该信号,并且直到从挂起信号集中除去该信号之后才会导致停止。 线程本身会除去它,或者您通过使用 PCSHOLDPCRUNPRSHOLD 选项设置挂起的信号集来除去它。

PCSSIG
指定特定线程或代表线程的当前信号及其关联的信号信息。 此信息是根据操作数 pr_siginfo64 结构设置的。 如果指定的信号号为零,那么将清除当前信号。 如果线程未在感兴趣的事件上停止,那么会返回错误 EbUSY

此操作的语法与 子例程, pthread__kill 子例程或 PCKILL中的语法不同。 使用 PCSSIG时,在执行恢复后立即将信号传递到线程 (即使信号处于挂起状态) ,并且即使跟踪信号,额外的 已发出信号 停止也不会进行干预。 将当前信号设置为 SIGKILL 将立即结束进程。

PCKILL
如果应用于进程控制文件,那么将使用与 子例程的语法相同的语法向进程发送信号。 如果应用于线程控制文件,那么将使用与 pthread__kill 子例程的语法相同的语法向线程发送信号。 该信号在消息中包含的操作数 国际 中命名。 发送 SIGKILL 将立即结束进程或线程。
PCUNKILL
指定要从暂挂信号集合中除去的信号。 如果应用于进程控制文件,那么将从进程的暂挂信号中删除该信号。 如果应用于线程控制文件,那么将从线程的暂挂信号中删除该信号。 当前信号 (如果有) 不受影响。 该信号在控制消息中的操作数 国际 中命名。 如果尝试删除 SIGKILL ,那么会导致错误 EINVAL
PCSHOLD
根据操作数 锡格塞特 结构为特定线程或代表线程设置保留信号的集合。 挂起的信号是那些如果发送到线程就会延迟传递的信号。 无法挂起 SIGKILLSIGSTOP 。 如果指定了此项,那么将以静默方式忽略这些项。
PC故障
定义要在此过程中跟踪的一组硬件故障。 发生其中一个故障时,线程将停止。 该集合是通过操作数 弗利采特 结构定义的。 故障名称在 <sys/procfs.h> 文件中定义,并包含以下内容:
注: 其中一些故障可能并非发生在所有处理器上; 除了此处描述的故障外,还可能存在其他特定于处理器的故障。
FLTILL
非法指令
FLTPRIV
特权指令
FLTBPT
断点陷阱
FLTTRACE
跟踪陷阱
FLTACESS
内存访问故障 (总线错误)
FLTBOUNDS
内存界限违例
FLTIOF
整数溢出
FLTIZDIV
整数除零
FLTFPE
浮点异常 (Floating-point exception
FLTSTACK
不可恢复的堆栈故障

如果未跟踪,那么故障通常会导致向发生故障的线程发出信号。 如果某个线程因故障而停止,那么除非 PCCFAULTPCRUNPRCFAULT 选项清除该故障,否则在恢复执行时,将向该线程发出信号。 /proc//状态/proc//lwp/标识/lwpstatus 中的 pr_info 字段标识要发送的信号,并包含有关故障的特定于机器的信息。

PCC故障
指定要清除的当前故障 (如果有)。 关联的信号不会发送到指定的线程或代表线程。
PC入口
指示进程的线程在进入指定的系统调用时停止。 要跟踪的系统调用的集合是通过操作数 sysset_t 结构定义的。 当跟踪系统调用的条目时,线程在开始对系统的调用之后,但在从线程访存系统调用参数之前停止。

如果线程在进入系统调用 (PR_SYSENTRY) 时或在可中断系统调用中休眠时停止 (设置了已入睡 ) ,那么可以通过在 PCRUN 控制消息中指定 PRSABORT 标志来指示该线程直接转至系统调用出口。 除非正在跟踪系统调用的出口,否则线程将返回到显示错误 EINTR的用户级别。

PC退出
指示进程的线程在退出指定的系统调用时停止。 要跟踪的系统调用的集合是通过操作数 sysset_t 结构定义的。 当跟踪从系统调用的出口时,线程在系统调用完成时停止,就在检查信号并返回到用户级别之前。 此时,所有的返回值都已存储到线程的寄存器中。
PCSET , PCRESET 和 PCUNSET
PCSET 为跟踪的进程设置一个或多个操作方式。 PCRESETPCUNSET 重置这些方式。 要设置或重置的方式由控制消息中的操作数 国际 中的标志指定:
PR_FORK (派生时继承)
当设置时,进程的跟踪标志由 弗福克 子例程的子例程继承。 重置时,子进程将在清除所有跟踪标志的情况下启动。
PR_RLC (运行-on-last-close)
当设置并关闭引用被跟踪进程或其任何线程的最后一个可写 /proc 文件描述符时,将清除该进程的所有跟踪标志,取消任何未完成的停止伪指令,并且如果在相关事件上停止任何线程,那么会将它们设置为正在运行,就好像对它们应用了 PCRUN 一样。 重置时,将保留进程的跟踪标志,并且不会将线程设置为在上次关闭时运行。
PR_KLC (在最后一个关闭时终止)
当设置并关闭引用跟踪的进程或其任何线程的最后一个可写 /proc 文件描述符时,该进程将随 SIGKILL退出。
PR_ASYNC (异步-停止)
如果设置了此参数,那么一个线程所关注的事件上的停止不会直接影响进程中的其他线程。 当重置并且线程在 PR_REQUESTED以外的其他相关事件上停止时,会指示进程中的所有其他线程停止。

如果您指定上述标志以外的标志,或者将这些操作应用于系统进程,那么将返回错误 EINVAL 。 当前方式将在 /proc//状态 文件的 pr_flags 字段中进行报告。

PCSREG
根据操作数 Prgregset_t 结构,为特定线程或代表线程设置常规寄存器和专用寄存器。 对于允许的更改集,可能存在特定于机器的限制。 如果线程未在相关事件上停止或者在内核中停止,那么 PCSREG 将失败并返回错误 EbUSY
PCSFPREG
根据操作数 弗普雷谢特 结构来设置特定线程或代表性线程的浮点寄存器。 如果系统不支持浮点运算 (没有浮点硬件,并且系统不模拟浮点机器指令) ,那么将返回错误 EINVAL 。 如果线程未在相关事件上停止或者在内核中停止,那么 PCSFPREG 将失败并返回错误 EbUSY
PCSVREG
根据操作数 普尔夫雷格塞特 结构来设置特定线程或代表性线程的向量寄存器。 如果系统不支持向量操作 (无向量硬件且系统不仿真向量机指令) ,或者如果代表性线程未引用向量单元,那么将返回错误 EINVAL 。 如果线程未在相关事件上停止或者在内核中停止,那么 PCSVREG 将失败并返回错误 EbUSY
PCNICE
所跟踪进程的 优先级将按操作数 国际中包含的数量递增。 只有超级用户可以通过这种方式提高进程的优先级,但任何用户都可能使优先级更差。 仅当应用于分时调度类中的进程时,此操作才有意义。

文件

描述
/proc 目录 (进程列表)
/proc/ 进程 的目录
/proc//状态 进程 的状态
/proc//ctl 进程 的控制文件
/proc//psinfo 进程 的 ps 信息
/proc//as 进程 的地址空间
/proc//map 作为流程 的映射信息
/proc//cred 进程 的凭证信息
/proc//对象 进程 的对象的目录
/proc//root 指向进程 的当前根目录的链接
/proc//mmap 进程 的内存映射文件信息
/proc//sigact 进程 的信号操作
/proc//sysent 进程 的系统调用信息
/proc//密码 链接到进程 的当前工作目录
/proc//fd 进程 的打开文件描述符的目录
/proc//lwp/标识 线程 标识 的目录
处理器//lwp/标识/lwpstatus 线程 标识 的状态
/proc//lwp/标识/lwpctl 线程 标识 的控制文件
/proc//lwp/标识/lwpsinfo 线程 标识 的 ps 信息

错误代码

除了通常与文件系统访问关联的错误之外,还可能发生其他错误:

错误代码 描述
ENOENT 跟踪的进程或线程在打开后已退出。
EFAULT 请求在无效的虚拟地址处开始。
EIO 在跟踪的进程中的非法地址尝试了 子例程。
EBUSY 由于下列其中一个原因,会返回此错误:
  • PCSTOPPCDSTOPPCWSTOP 已应用到系统进程。
  • 在已打开以进行写入的进程文件上尝试了互斥 子例程。
  • PCRUNPCSSIGPCSREGPCSFPREG 已应用于未在相关事件中停止的进程或线程。
  • /proc 文件系统已安装时,尝试安装该文件系统。
EPERM 除特权用户以外的其他用户尝试通过发出 PCNICE来提高进程的优先级。
ENOSYS 已尝试对 /proc 文件系统中的条目执行不受支持的操作 (例如,创建,除去,链接或取消链接)。
EINVAL 为系统调用提供了无效的参数。 以下是可能导致此错误的一些 (但并非全部) 可能的条件:
  • 未定义控制消息操作码。
  • 控制消息的格式不正确。
  • 在不支持单步执行的实现上使用了 PCRUN 操作的 PRSTEP 选项。
  • 已使用 PCSSIGPCKILLPCUNKILL指定了超出范围的信号号。
  • SIGKILL 是使用 PCUNKILL指定的。
  • PCSFPREG 已在不支持浮点的机器上应用。
  • PCSVREG 已在没有向量支持的机器上应用,或者已应用于未引用该向量单元的线程。
EINTR 当等待跟踪的进程或线程通过 PCSTOPPCWSTOP停止时,控制进程接收到信号。
EBADF 跟踪的进程对 setuid/setgid 对象文件或该进程不可读的对象文件执行了 执行 子例程。 对进程或线程文件描述符 ( 关闭 子例程除外) 执行的所有其他操作都会引起此错误。

安全性

对于跟踪的进程,控制消息的效果保证是原子的。

出于安全原因,除了特权用户之外, /proc 文件的 子例程失败,除非调用者的有效用户标识和有效组标识都与跟踪的进程和进程的对象文件的有效用户标识和有效组标识相匹配。 只有特权用户才能打开对应于 设置标识设置标识 进程的文件。 即使由特权用户持有,如果被跟踪的进程对 setuid/setgid 对象文件或它无法读取的对象文件执行 执行 子例程,那么打开的进程或线程文件描述符将变为无效。 对无效文件描述符执行的任何操作 ( 关闭 子例程除外) 都失败,并返回 EBADF。 在此情况下,如果设置了任何跟踪标志,并且进程或任何线程文件打开以进行写入,那么将指示进程停止并设置其 "在最后一个关闭时运行" 标志 (请参阅 PCSET)。

此功能部件使控制进程 (具有必需的许可权) 能够重新打开进程文件以获取新的有效文件描述符,关闭无效文件描述符,然后继续。 仅关闭无效文件描述符会导致跟踪的进程在未设置任何跟踪标志的情况下恢复执行。 当前未打开以使用先前 子例程留下的跟踪标志进行写入,并且对 setuid/setgid 或不可读对象文件执行 执行 子例程的任何进程都不会停止。 但是,该进程并未清除其所有跟踪标志。