我正在尝试编写一个以几个进程作为参数的程序。然后,父进程执行每个子进程并打印出有关该子进程的一些统计信息。
示例:/ generate ls -l //将导致打印程序的结果列出有关ls -l的一些统计信息(具体是它的系统时间,用户时间和上下文切换次数)。
我不想使用getrusage()函数,而是希望从中获取必要的信息。 Proc文件系统。现在,我的理解是,如果我要使用wait()函数,它将最终从proc文件系统中删除信息。我在下面包含了我的代码
#include <time.h>
#include <stdbool.h>
#include <assert.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/resource.h>
void inputted_command(int a, char **b){
for(int i=1;i<a;i++)
printf("%s ",b[i]);
}
int main(int argc, char **argv){
int status;
pid_t childpid;
pid_t get_information;
if (argc < 2)
{
return 1;
}
bool handle_signals = (signal(SIGINT, SIG_IGN) != SIG_IGN);
clock_t t;
t= clock();
pid_t pid = fork();
if(pid<0)
{
printf("fork: error no = %s\n",strerror(errno));
return 1;
}
else if(pid>0){
signal(SIGINT,SIG_IGN);
sleep(60);
/*
get_information=fork();
if(get_information==0){
excelp(___);
}else
waitpid(pid, &status, 0);
*/
waitpid(childpid, &status, 0);
t= clock()-t;
double real_time_taken = ((double)t)/CLOCKS_PER_SEC;
printf("The command ");
inputted_command(argc,argv);
if(WIFSIGNALED(status)){
printf("is interrupted by the signal number = %d (Insert Name Here) real: %.2f, user: , system: , context switch: \n",WTERMSIG(status),real_time_taken);
}
else{
printf("terminated with return status code = %d real: %.2f, user: , system: , context switch: \n",WEXITSTATUS(status), real_time_taken);
}
}
else if(pid==0){
childpid=getpid();
printf("Process with id: %d created for the command: ",(int)getpid());
inputted_command(argc,argv);
printf("\n");
assert(pid == 0);
if (handle_signals)
signal(SIGINT, SIG_DFL);
execvp(argv[1], &argv[1]);
printf(" experienced an error in starting the command: ");
inputted_command(argc,argv);
printf("\n");
exit(-1);
}
}
所以我在这里的主要问题是,这是否是获取信息的适当方法子进程的信息,以及如何获取信息(主要是系统时间,用户时间以及自愿和非自愿上下文切换?
答案 0 :(得分:1)
这是我编写的一个测试程序,可能会有所启发(注意:有点粗糙):
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
int mode = -1;
pid_t pid;
time_t cur;
FILE *xf;
char dirproc[100];
char dirfd[100];
char status_file[100];
char cmd[100];
void
xsystem(char *cmd)
{
printf("CMD: %s\n",cmd);
system(cmd);
}
int
check(int nmode)
{
struct stat st;
int errst;
int errkill;
char buf[500];
errkill = kill(pid,0);
errst = stat(dirproc,&st);
if (nmode != mode) {
printf("elap=%d errkill=%d errst=%d\n",cur,errkill,errst);
sprintf(cmd,"ls -l /proc/%d",pid);
xsystem(cmd);
sprintf(cmd,"ls -l /proc/%d/fd",pid);
xsystem(cmd);
sprintf(cmd,"cat /proc/%d/status",pid);
xsystem(cmd);
printf("fgets\n");
rewind(xf);
while (1) {
char *cp = fgets(buf,sizeof(buf),xf);
if (cp == NULL)
break;
fputs(buf,stdout);
}
mode = nmode;
}
return errkill;
}
// main -- main program
int
main(int argc,char **argv)
{
char *cp;
--argc;
++argv;
for (; argc > 0; --argc, ++argv) {
cp = *argv;
if (*cp != '-')
break;
switch (cp[1]) {
default:
break;
}
}
setlinebuf(stdout);
setlinebuf(stderr);
pid = fork();
if (pid == 0) {
open("/dev/null",O_RDONLY);
sleep(1);
exit(0);
}
sprintf(dirproc,"/proc/%d",pid);
sprintf(dirfd,"/proc/%d/fd",pid);
sprintf(status_file,"/proc/%d/status",pid);
xf = fopen(status_file,"r");
time_t beg = time(NULL);
cur = 0;
while (1) {
cur = time(NULL);
cur -= beg;
if (cur >= 4)
break;
check(1);
}
printf("\n");
printf("postloop\n");
check(2);
waitpid(pid,NULL,0);
printf("\n");
printf("postwait\n");
check(3);
return 0;
}
这是程序输出:
elap=0 errkill=0 errst=0
CMD: ls -l /proc/94913
total 0
dr-xr-xr-x. 2 xxx xxx 0 Oct 21 15:50 attr
-rw-r--r--. 1 xxx xxx 0 Oct 21 15:50 autogroup
-r--------. 1 xxx xxx 0 Oct 21 15:50 auxv
-r--r--r--. 1 xxx xxx 0 Oct 21 15:50 cgroup
--w-------. 1 xxx xxx 0 Oct 21 15:50 clear_refs
-r--r--r--. 1 xxx xxx 0 Oct 21 15:50 cmdline
-rw-r--r--. 1 xxx xxx 0 Oct 21 15:50 comm
-rw-r--r--. 1 xxx xxx 0 Oct 21 15:50 coredump_filter
-r--r--r--. 1 xxx xxx 0 Oct 21 15:50 cpuset
lrwxrwxrwx. 1 xxx xxx 0 Oct 21 15:50 cwd -> /tmp/cld
-r--------. 1 xxx xxx 0 Oct 21 15:50 environ
lrwxrwxrwx. 1 xxx xxx 0 Oct 21 15:50 exe -> /tmp/cld/pgm2
dr-x------. 2 xxx xxx 0 Oct 21 15:50 fd
dr-x------. 2 xxx xxx 0 Oct 21 15:50 fdinfo
-rw-r--r--. 1 xxx xxx 0 Oct 21 15:50 gid_map
-r--------. 1 xxx xxx 0 Oct 21 15:50 io
-r--r--r--. 1 xxx xxx 0 Oct 21 15:50 latency
-r--r--r--. 1 xxx xxx 0 Oct 21 15:50 limits
-rw-r--r--. 1 xxx xxx 0 Oct 21 15:50 loginuid
dr-x------. 2 xxx xxx 0 Oct 21 15:50 map_files
-r--r--r--. 1 xxx xxx 0 Oct 21 15:50 maps
-rw-------. 1 xxx xxx 0 Oct 21 15:50 mem
-r--r--r--. 1 xxx xxx 0 Oct 21 15:50 mountinfo
-r--r--r--. 1 xxx xxx 0 Oct 21 15:50 mounts
-r--------. 1 xxx xxx 0 Oct 21 15:50 mountstats
dr-xr-xr-x. 6 xxx xxx 0 Oct 21 15:50 net
dr-x--x--x. 2 xxx xxx 0 Oct 21 15:50 ns
-r--r--r--. 1 xxx xxx 0 Oct 21 15:50 numa_maps
-rw-r--r--. 1 xxx xxx 0 Oct 21 15:50 oom_adj
-r--r--r--. 1 xxx xxx 0 Oct 21 15:50 oom_score
-rw-r--r--. 1 xxx xxx 0 Oct 21 15:50 oom_score_adj
-r--------. 1 xxx xxx 0 Oct 21 15:50 pagemap
-r--------. 1 xxx xxx 0 Oct 21 15:50 personality
-rw-r--r--. 1 xxx xxx 0 Oct 21 15:50 projid_map
lrwxrwxrwx. 1 xxx xxx 0 Oct 21 15:50 root -> /
-rw-r--r--. 1 xxx xxx 0 Oct 21 15:50 sched
-r--r--r--. 1 xxx xxx 0 Oct 21 15:50 schedstat
-r--r--r--. 1 xxx xxx 0 Oct 21 15:50 sessionid
-rw-r--r--. 1 xxx xxx 0 Oct 21 15:50 setgroups
-r--r--r--. 1 xxx xxx 0 Oct 21 15:50 smaps
-r--r--r--. 1 xxx xxx 0 Oct 21 15:50 smaps_rollup
-r--------. 1 xxx xxx 0 Oct 21 15:50 stack
-r--r--r--. 1 xxx xxx 0 Oct 21 15:50 stat
-r--r--r--. 1 xxx xxx 0 Oct 21 15:50 statm
-r--r--r--. 1 xxx xxx 0 Oct 21 15:50 status
-r--------. 1 xxx xxx 0 Oct 21 15:50 syscall
dr-xr-xr-x. 3 xxx xxx 0 Oct 21 15:50 task
-r--r--r--. 1 xxx xxx 0 Oct 21 15:50 timers
-rw-rw-rw-. 1 xxx xxx 0 Oct 21 15:50 timerslack_ns
-rw-r--r--. 1 xxx xxx 0 Oct 21 15:50 uid_map
-r--r--r--. 1 xxx xxx 0 Oct 21 15:50 wchan
CMD: ls -l /proc/94913/fd
total 0
lrwx------. 1 xxx xxx 64 Oct 21 15:50 0 -> /dev/pts/0
l-wx------. 1 xxx xxx 64 Oct 21 15:50 1 -> /tmp/out2
l-wx------. 1 xxx xxx 64 Oct 21 15:50 2 -> /tmp/out2
lr-x------. 1 xxx xxx 64 Oct 21 15:50 3 -> /dev/null
CMD: cat /proc/94913/status
Name: pgm2
Umask: 0022
State: S (sleeping)
Tgid: 94913
Ngid: 0
Pid: 94913
PPid: 94912
TracerPid: 0
Uid: 500 500 500 500
Gid: 500 500 500 500
FDSize: 64
Groups: 500
NStgid: 94913
NSpid: 94913
NSpgid: 94912
NSsid: 3771
VmPeak: 4136 kB
VmSize: 4136 kB
VmLck: 0 kB
VmPin: 0 kB
VmHWM: 80 kB
VmRSS: 80 kB
RssAnon: 80 kB
RssFile: 0 kB
RssShmem: 0 kB
VmData: 44 kB
VmStk: 132 kB
VmExe: 8 kB
VmLib: 1872 kB
VmPTE: 52 kB
VmSwap: 0 kB
HugetlbPages: 0 kB
CoreDumping: 0
Threads: 1
SigQ: 0/47895
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000000000
SigCgt: 0000000000000000
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000
NoNewPrivs: 0
Seccomp: 0
Speculation_Store_Bypass: thread vulnerable
Cpus_allowed: ff
Cpus_allowed_list: 0-7
Mems_allowed: 00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001
Mems_allowed_list: 0
voluntary_ctxt_switches: 1
nonvoluntary_ctxt_switches: 0
fgets
Name: pgm2
Umask: 0022
State: S (sleeping)
Tgid: 94913
Ngid: 0
Pid: 94913
PPid: 94912
TracerPid: 0
Uid: 500 500 500 500
Gid: 500 500 500 500
FDSize: 64
Groups: 500
NStgid: 94913
NSpid: 94913
NSpgid: 94912
NSsid: 3771
VmPeak: 4136 kB
VmSize: 4136 kB
VmLck: 0 kB
VmPin: 0 kB
VmHWM: 80 kB
VmRSS: 80 kB
RssAnon: 80 kB
RssFile: 0 kB
RssShmem: 0 kB
VmData: 44 kB
VmStk: 132 kB
VmExe: 8 kB
VmLib: 1872 kB
VmPTE: 52 kB
VmSwap: 0 kB
HugetlbPages: 0 kB
CoreDumping: 0
Threads: 1
SigQ: 0/47895
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000000000
SigCgt: 0000000000000000
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000
NoNewPrivs: 0
Seccomp: 0
Speculation_Store_Bypass: thread vulnerable
Cpus_allowed: ff
Cpus_allowed_list: 0-7
Mems_allowed: 00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001
Mems_allowed_list: 0
voluntary_ctxt_switches: 1
nonvoluntary_ctxt_switches: 0
postloop
elap=4 errkill=0 errst=0
CMD: ls -l /proc/94913
ls: cannot read symbolic link '/proc/94913/cwd': No such file or directory
ls: cannot read symbolic link '/proc/94913/root': No such file or directory
ls: cannot read symbolic link '/proc/94913/exe': No such file or directory
total 0
dr-xr-xr-x. 2 xxx xxx 0 Oct 21 15:50 attr
-rw-r--r--. 1 root root 0 Oct 21 15:50 autogroup
-r--------. 1 root root 0 Oct 21 15:50 auxv
-r--r--r--. 1 root root 0 Oct 21 15:50 cgroup
--w-------. 1 root root 0 Oct 21 15:50 clear_refs
-r--r--r--. 1 root root 0 Oct 21 15:50 cmdline
-rw-r--r--. 1 root root 0 Oct 21 15:50 comm
-rw-r--r--. 1 root root 0 Oct 21 15:50 coredump_filter
-r--r--r--. 1 root root 0 Oct 21 15:50 cpuset
lrwxrwxrwx. 1 root root 0 Oct 21 15:50 cwd
-r--------. 1 root root 0 Oct 21 15:50 environ
lrwxrwxrwx. 1 root root 0 Oct 21 15:50 exe
dr-x------. 2 root root 0 Oct 21 15:50 fd
dr-x------. 2 root root 0 Oct 21 15:50 fdinfo
-rw-r--r--. 1 root root 0 Oct 21 15:50 gid_map
-r--------. 1 root root 0 Oct 21 15:50 io
-r--r--r--. 1 root root 0 Oct 21 15:50 latency
-r--r--r--. 1 root root 0 Oct 21 15:50 limits
-rw-r--r--. 1 root root 0 Oct 21 15:50 loginuid
dr-x------. 2 root root 0 Oct 21 15:50 map_files
-r--r--r--. 1 root root 0 Oct 21 15:50 maps
-rw-------. 1 root root 0 Oct 21 15:50 mem
-r--r--r--. 1 root root 0 Oct 21 15:50 mountinfo
-r--r--r--. 1 root root 0 Oct 21 15:50 mounts
-r--------. 1 root root 0 Oct 21 15:50 mountstats
dr-xr-xr-x. 2 xxx xxx 0 Oct 21 15:50 net
dr-x--x--x. 2 root root 0 Oct 21 15:50 ns
-r--r--r--. 1 root root 0 Oct 21 15:50 numa_maps
-rw-r--r--. 1 root root 0 Oct 21 15:50 oom_adj
-r--r--r--. 1 root root 0 Oct 21 15:50 oom_score
-rw-r--r--. 1 root root 0 Oct 21 15:50 oom_score_adj
-r--------. 1 root root 0 Oct 21 15:50 pagemap
-r--------. 1 root root 0 Oct 21 15:50 personality
-rw-r--r--. 1 root root 0 Oct 21 15:50 projid_map
lrwxrwxrwx. 1 root root 0 Oct 21 15:50 root
-rw-r--r--. 1 root root 0 Oct 21 15:50 sched
-r--r--r--. 1 root root 0 Oct 21 15:50 schedstat
-r--r--r--. 1 root root 0 Oct 21 15:50 sessionid
-rw-r--r--. 1 root root 0 Oct 21 15:50 setgroups
-r--r--r--. 1 root root 0 Oct 21 15:50 smaps
-r--r--r--. 1 root root 0 Oct 21 15:50 smaps_rollup
-r--------. 1 root root 0 Oct 21 15:50 stack
-r--r--r--. 1 root root 0 Oct 21 15:50 stat
-r--r--r--. 1 root root 0 Oct 21 15:50 statm
-r--r--r--. 1 root root 0 Oct 21 15:50 status
-r--------. 1 root root 0 Oct 21 15:50 syscall
dr-xr-xr-x. 3 xxx xxx 0 Oct 21 15:50 task
-r--r--r--. 1 root root 0 Oct 21 15:50 timers
-rw-rw-rw-. 1 root root 0 Oct 21 15:50 timerslack_ns
-rw-r--r--. 1 root root 0 Oct 21 15:50 uid_map
-r--r--r--. 1 root root 0 Oct 21 15:50 wchan
CMD: ls -l /proc/94913/fd
ls: cannot open directory '/proc/94913/fd': Permission denied
CMD: cat /proc/94913/status
Name: pgm2
State: Z (zombie)
Tgid: 94913
Ngid: 0
Pid: 94913
PPid: 94912
TracerPid: 0
Uid: 500 500 500 500
Gid: 500 500 500 500
FDSize: 0
Groups: 500
NStgid: 94913
NSpid: 94913
NSpgid: 94912
NSsid: 3771
Threads: 1
SigQ: 0/47895
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000000000
SigCgt: 0000000000000000
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000
NoNewPrivs: 0
Seccomp: 0
Speculation_Store_Bypass: thread vulnerable
Cpus_allowed: ff
Cpus_allowed_list: 0-7
Mems_allowed: 00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001
Mems_allowed_list: 0
voluntary_ctxt_switches: 2
nonvoluntary_ctxt_switches: 0
fgets
Name: pgm2
State: Z (zombie)
Tgid: 94913
Ngid: 0
Pid: 94913
PPid: 94912
TracerPid: 0
Uid: 500 500 500 500
Gid: 500 500 500 500
FDSize: 0
Groups: 500
NStgid: 94913
NSpid: 94913
NSpgid: 94912
NSsid: 3771
Threads: 1
SigQ: 0/47895
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000000000
SigCgt: 0000000000000000
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000
NoNewPrivs: 0
Seccomp: 0
Speculation_Store_Bypass: thread vulnerable
Cpus_allowed: ff
Cpus_allowed_list: 0-7
Mems_allowed: 00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001
Mems_allowed_list: 0
voluntary_ctxt_switches: 2
nonvoluntary_ctxt_switches: 0
postwait
elap=4 errkill=-1 errst=-1
CMD: ls -l /proc/94913
ls: cannot access '/proc/94913': No such file or directory
CMD: ls -l /proc/94913/fd
ls: cannot access '/proc/94913/fd': No such file or directory
CMD: cat /proc/94913/status
cat: /proc/94913/status: No such file or directory
fgets
谢谢。我对时间问题感到好奇。如果wait-family调用释放了/ proc中PID的信息,那么启动PID的进程在知道终止子进程之后如何读取状态伪文件。
没有使用wait
,父级无法确定/轻松/明确地知道,因为存在另一种检查活动进程的方式(例如{ 1}})仍然返回0。这令我有些惊讶。
基于测试程序的输出,可能的一种工作方式是在kill(pid,0)
上执行readlink
并检查错误(即错误表示进程已退出并处于僵尸状态)。
另一种方法是阅读/proc/pid/cwd
并查找:/proc/pid/status
是否需要在等待之前打开状态文件,然后在等待返回后再读取它?
完成State: Z (zombie)
之后,即使wait
上打开 pre 的流也返回EOF。所以,没有喜悦。
还是它不那么狡猾? / proc文件系统上应该有一些文档,例如man7.org上的proc(5),应该涵盖这些详细信息。
手册页中还有其他一些文件,这些文件在进程变为僵尸时会更改(例如/proc/pid/status
)
答案 1 :(得分:0)
有了Craig Estey的answer的推动力,接着是我的comment,并使用POSIX的信息sigaction()
,它指向Signal Actions
和<signal.h>
,
我想出了以下代码,该代码对SA_SIGINFO
信号使用SIGCHLD
处理,该程序允许程序从/proc
文件系统中收集子进程终止后但之前的信息。已经等待了。
siginfo47.c
#define _XOPEN_SOURCE 700
#include "stderr.h"
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
static int got_signal = 0;
static siginfo_t child_info = { 0 };
static void sigchld(int signum, siginfo_t *info, void *ctxt)
{
assert(info != 0);
assert(ctxt != 0);
assert(signum == info->si_signo);
got_signal = signum;
child_info = *info;
}
struct si_code_names
{
int si_code;
char si_code_name[16];
char si_code_meaning[64];
};
static struct si_code_names si_codes[] =
{
[CLD_EXITED] = { CLD_EXITED, "CLD_EXITED", "Child has exited." },
[CLD_KILLED] = { CLD_KILLED, "CLD_KILLED", "Child has terminated abnormally and did not create a core file." },
[CLD_DUMPED] = { CLD_DUMPED, "CLD_DUMPED", "Child has terminated abnormally and created a core file." },
[CLD_TRAPPED] = { CLD_TRAPPED, "CLD_TRAPPED", "Traced child has trapped." },
[CLD_STOPPED] = { CLD_STOPPED, "CLD_STOPPED", "Child has stopped." },
[CLD_CONTINUED] = { CLD_CONTINUED, "CLD_CONTINUED", "Stopped child has continued." },
};
static void cat_proc_file(int pid, const char *base)
{
char buffer[1024];
int rc;
rc = snprintf(buffer, sizeof(buffer), "/proc/%d/%s", pid, base);
if (rc < 0 || rc >= (int)sizeof(buffer))
err_error("snprintf() failed - can't happen!?!\n");
int fd = open(buffer, O_RDONLY);
if (fd < 0)
err_syserr("failed to open file '%s' for reading: ", buffer);
printf("Contents of %s:\n", buffer);
int nbytes;
while ((nbytes = read(fd, buffer, sizeof(buffer))) > 0)
printf("%*.*s", nbytes, nbytes, buffer);
putchar('\n');
fflush(stdout);
close(fd);
}
int main(int argc, char **argv)
{
char *cmdv[] = { "ls", "-l", 0 };
err_setarg0(argv[0]);
if (argc <= 1)
{
argc = 2;
argv = cmdv;
}
else
{
argc--;
argv++;
}
pid_t pid = fork();
if (pid < 0)
err_syserr("failed to fork: ");
else if (pid > 0)
{
struct sigaction sa = { 0 };
sa.sa_sigaction = sigchld;
sa.sa_flags = SA_SIGINFO;
if (sigaction(SIGCHLD, &sa, 0) != 0)
err_syserr("failed to set signal handling: ");
printf("Parent PID %d: pausing while PID %d runs\n", (int)getpid(), (int)pid);
fflush(stdout);
pause();
printf("Parent PID %d: unpaused\n", (int)getpid());
printf("Stashed information:\n");
printf(" Signal: %d\n", got_signal);
printf(" si_signo: %d\n", child_info.si_signo);
printf(" si_code: %d\n", child_info.si_code);
if (child_info.si_signo == SIGCHLD)
{
struct si_code_names *code = &si_codes[child_info.si_code];
printf(" [%s] %s\n", code->si_code_name,
code->si_code_meaning);
}
printf(" si_pid: %d\n", (int)child_info.si_pid);
printf(" si_uid: %d\n", (int)child_info.si_uid);
printf(" si_addr: 0x%12" PRIXPTR "\n", (uintptr_t)child_info.si_addr);
printf(" si_status: %d\n", child_info.si_code);
printf(" si_value.int: %d\n", child_info.si_value.sival_int);
cat_proc_file(pid, "stat");
cat_proc_file(pid, "status");
int status;
int corpse;
if ((corpse = waitpid(pid, &status, 0)) != pid)
err_syserr("failed to wait for child %d", pid);
if (WIFSIGNALED(status))
printf("PID %d died from signal number = %d (0x%.4X)\n",
corpse, WTERMSIG(status), status);
else if (WIFEXITED(status))
printf("PID %d exited normally with status = %d (0x%.4X)\n",
corpse, WEXITSTATUS(status), status);
else
printf("PID %d was neither signalled nor exited normally (0x%.4X)\n",
corpse, status);
}
else if (pid == 0)
{
printf("PID: %d:", (int)getpid());
for (int i = 0; argv[i] != 0; i++)
printf(" %s", argv[i]);
putchar('\n');
fflush(stdout);
execvp(argv[0], &argv[0]);
err_syserr("failed to execute %s: ", argv[0]);
/*NOTREACHED*/
}
}
其中一些代码可从我在GitHub上的SOQ(堆栈溢出问题)存储库中获得。具体来说,文件stderr.c
和stderr.h
可以在src/libsoq子目录中找到。它们极大地简化了错误报告。
示例运行包括:
$ siginfo47
Parent PID 15016: pausing while PID 15017 runs
PID: 15017: ls -l
total 400
drwxr-xr-x 2 jleffler pd 4096 Oct 21 15:16 bin
drwxr-xr-x 5 jleffler pd 256 Oct 21 15:15 doc
drwxr-xr-x 2 jleffler pd 4096 Oct 21 15:15 etc
drwxr-xr-x 2 jleffler pd 4096 Oct 21 15:16 inc
drwxr-xr-x 2 jleffler pd 256 Oct 21 15:16 lib
-rw-r--r-- 1 jleffler pd 22072 Oct 21 15:15 LICENSE.md
-rw-r--r-- 1 jleffler pd 390 Oct 21 15:15 makefile
drwxr-xr-x 2 jleffler pd 256 Oct 21 15:15 packages
-rw-r--r-- 1 jleffler pd 2694 Oct 21 15:15 README.md
-rwxr-xr-x 1 jleffler pd 64968 Oct 21 15:17 siginfo41
-rw-r--r-- 1 jleffler pd 5990 Oct 21 15:17 siginfo41.c
-rwxr-xr-x 1 jleffler pd 66104 Oct 21 15:34 siginfo47
-rw-r--r-- 1 jleffler pd 7417 Oct 21 15:33 siginfo47.c
drwxr-xr-x 230 jleffler pd 8192 Oct 21 15:15 src
Parent PID 15016: unpaused
Stashed information:
Signal: 17
si_signo: 17
si_code: 1
[CLD_EXITED] Child has exited.
si_pid: 15017
si_uid: 9508
si_addr: 0x252400003AA9
si_status: 1
si_value.int: 0
Contents of /proc/15017/stat:
15017 (ls) Z 15016 15016 13211 34827 15016 4227084 452 0 0 0 0 0 0 0 20 0 1 0 511347844 0 0 18446744073709551615 0 0 0 0 0 0 0 0 0 18446744073709551615 0 0 17 6 0 0 0 0 0 0 0 0 0 0 0 0 0
Contents of /proc/15017/status:
Name: ls
State: Z (zombie)
Tgid: 15017
Ngid: 0
Pid: 15017
PPid: 15016
TracerPid: 0
Uid: 9508 9508 9508 9508
Gid: 1240 1240 1240 1240
FDSize: 0
Groups: 297 1240 1360 8714
Threads: 1
SigQ: 0/71487
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000000000
SigCgt: 0000000180000000
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: 0000001fffffffff
CapAmb: 0000000000000000
Seccomp: 0
Cpus_allowed: ff
Cpus_allowed_list: 0-7
Mems_allowed: 00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001
Mems_allowed_list: 0
voluntary_ctxt_switches: 3
nonvoluntary_ctxt_switches: 1
PID 15017 exited normally with status = 0 (0x0000)
$ siginfo47 exitcode 23
Parent PID 15032: pausing while PID 15033 runs
PID: 15033: exitcode 23
Parent PID 15032: unpaused
Stashed information:
Signal: 17
si_signo: 17
si_code: 1
[CLD_EXITED] Child has exited.
si_pid: 15033
si_uid: 9508
si_addr: 0x252400003AB9
si_status: 1
si_value.int: 23
Contents of /proc/15033/stat:
15033 (exitcode) Z 15032 15032 13211 34827 15032 4227084 179 0 0 0 0 0 0 0 20 0 1 0 511349111 0 0 18446744073709551615 0 0 0 0 0 0 0 0 0 18446744073709551615 0 0 17 5 0 0 0 0 0 0 0 0 0 0 0 0 0
Contents of /proc/15033/status:
Name: exitcode
State: Z (zombie)
Tgid: 15033
Ngid: 0
Pid: 15033
PPid: 15032
TracerPid: 0
Uid: 9508 9508 9508 9508
Gid: 1240 1240 1240 1240
FDSize: 0
Groups: 297 1240 1360 8714
Threads: 1
SigQ: 0/71487
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000000000
SigCgt: 0000000000000000
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: 0000001fffffffff
CapAmb: 0000000000000000
Seccomp: 0
Cpus_allowed: ff
Cpus_allowed_list: 0-7
Mems_allowed: 00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001
Mems_allowed_list: 0
voluntary_ctxt_switches: 3
nonvoluntary_ctxt_switches: 1
PID 15033 exited normally with status = 23 (0x1700)
$ siginfo47 exitcode -s 13
PID: 15057: exitcode -s 13
Parent PID 15056: pausing while PID 15057 runs
Parent PID 15056: unpaused
Stashed information:
Signal: 17
si_signo: 17
si_code: 2
[CLD_KILLED] Child has terminated abnormally and did not create a core file.
si_pid: 15057
si_uid: 9508
si_addr: 0x252400003AD1
si_status: 2
si_value.int: 13
Contents of /proc/15057/stat:
15057 (exitcode) Z 15056 15056 13211 34827 15056 4228108 177 0 0 0 0 0 0 0 20 0 1 0 511350462 0 0 18446744073709551615 0 0 0 0 0 4096 0 0 0 18446744073709551615 0 0 17 5 0 0 0 0 0 0 0 0 0 0 0 0 0
Contents of /proc/15057/status:
Name: exitcode
State: Z (zombie)
Tgid: 15057
Ngid: 0
Pid: 15057
PPid: 15056
TracerPid: 0
Uid: 9508 9508 9508 9508
Gid: 1240 1240 1240 1240
FDSize: 0
Groups: 297 1240 1360 8714
Threads: 1
SigQ: 1/71487
SigPnd: 0000000000001000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000000000
SigCgt: 0000000000000000
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: 0000001fffffffff
CapAmb: 0000000000000000
Seccomp: 0
Cpus_allowed: ff
Cpus_allowed_list: 0-7
Mems_allowed: 00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001
Mems_allowed_list: 0
voluntary_ctxt_switches: 2
nonvoluntary_ctxt_switches: 1
PID 15057 died from signal number = 13 (0x000D)
$ exitcode -h
Usage: exitcode [-hV] [-s signal] [exit-status]
-h Print this help message and exit
-s signal Kill self with signal number
-V Print version information and exit
$
如帮助消息所示,exitcode
程序以退出状态死掉,退出状态通常是(exitcode 23
)或由于信号(exitcode -s 13
)导致的。