How to get the full returned value of a child process?

瘦欲@ 提交于 2021-01-23 07:53:46

问题


I need to catch the returned value of a child process..

The problem is: with using the waitpid() function I can catch only 8 bits of the returned value

WEXITSTATUS(wstatus) returns the exit status of the child. This consists of the least significant 8 bits of the status argument that the child specified in a call to exit(3) or _exit(2) or as the argument for a return statement in main(). This macro should be employed only if WIFEXITED returned true.

How can I catch the full int value that is returned from main() ?

EDIT: Stackoverflow forced me to edit the question as it linked another answered question but it has nothing to do with mine!


回答1:


POSIX requires that the full exit value be passed in the si_status member of the siginfo_t structure passed to the SIGCHLD handler, if it is appropriately established via a call to sigaction with SA_SIGINFO specified in the flags:

If si_code is equal to CLD_EXITED, then si_status holds the exit value of the process; otherwise, it is equal to the signal that caused the process to change state. The exit value in si_status shall be equal to the full exit value (that is, the value passed to _exit(), _Exit(), or exit(), or returned from main()); it shall not be limited to the least significant eight bits of the value.

(Emphasis mine).

Note that upon testing, it appears that Linux does not honour this requirement and returns only the lower 8 bits of the exit code in the si_status member. Other operating systems may correctly return the full status; FreeBSD does. See test program here.

Be wary, though, that is not completely clear that you will receive an individual SIGCHLD signal for every child process termination (multiple pending instances of a signal can be merged), so this technique is not completely infallible. It is probably better to find another way to communicate a value between processes if you need more than 8 bits.




回答2:


The short answer is that you pretty much can't. Traditionally, the exit status of a process under Unix/Linux is propagated as an 8-bit value. You can return any integer from main that you like, you can call exit with any integer that you like, but only the low-order 8 bits are available to the parent via any of the wait functions.

The reason WEXITSTATUSis documented as returning only the low-order 8 bits of the status is that those are the only bits that there are.

If you're trying to pass arbitrary data from a subprocess back to its parent, the exit status is not the way to do it. Me, I normally print data to the standard output, and have the caller capture it using popen or the equivalent.


Addendum: I thought the kernel didn't even record the full int-sized exit status, and that it was therefore impossible to retrieve it by any means, but as davmac explains in another answer, you might be able to get your hands on it in a SIGCHLD handler.




回答3:


I believe the only ways you can get it is by straceing the process and looking for the exit system calls, which now seem to be exit_group, by debugging, or possibly by using some ugly hacks like LD_PRELOAD. I.e. nothing unintrusive.

For zombie processes the exit code can be found in the last column of /proc/<pid>/stat but it is already & 0xFF.



来源:https://stackoverflow.com/questions/50982730/how-to-get-the-full-returned-value-of-a-child-process

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!