Date: Fri, 15 Nov 2013 15:28:12 GMT From: Dmitrijs Ledkovs <xnox@debian.org> To: freebsd-gnats-submit@FreeBSD.org Subject: misc/184002: wait6 / waitid returns wrong value in siginfo.si_status Message-ID: <201311151528.rAFFSCQ2079936@oldred.freebsd.org> Resent-Message-ID: <201311151530.rAFFU0Ah091686@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 184002 >Category: misc >Synopsis: wait6 / waitid returns wrong value in siginfo.si_status >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Fri Nov 15 15:30:00 UTC 2013 >Closed-Date: >Last-Modified: >Originator: Dmitrijs Ledkovs >Release: 9.2, 10 >Organization: Debian >Environment: GNU/kFreeBSD kfree 10.0-0-amd64 #0 Fri Aug 2 21:27:23 CEST 2013 x86_64 amd64 QEMU Virtual CPU version 1.6.1 GNU/kFreeBSD >Description: As per http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html siginfo_t.si_status is "Exit value or signal." The waitid call is suppose to fill in siginfo_t structure if one was passed to the function http://pubs.opengroup.org/onlinepubs/9699919799/functions/waitid.html Instead at the moment the returned siginfo_t.si_status of FreeBSD is same on as &status returned by waitpid() call. I.E. value which hasn't been extraced with WEXITSTATUS() >How-To-Repeat: The below program should not assert. #include <sys/types.h> #include <sys/wait.h> #include <stdlib.h> #include <assert.h> int main() { siginfo_t siginfo; pid_t pid = -1; pid = fork (); if (pid > 0) { waitid (P_PID, pid, &siginfo, WEXITED | WNOWAIT); assert (siginfo.si_code == CLD_EXITED); assert (siginfo.si_status == 123); } else if (pid == 0) { exit (123); } } >Fix: Untested patch against kfreebsd-source-10.0/sys/kern/kern_exit.c --- kern_exit.c.orig 2013-11-15 15:23:25.000000000 +0000 +++ kern_exit.c 2013-11-15 15:26:26.000000000 +0000 @@ -975,16 +975,18 @@ * cases TRAPPED, STOPPED, and CONTINUED later. */ if (WCOREDUMP(p->p_xstat)) siginfo->si_code = CLD_DUMPED; - else if (WIFSIGNALED(p->p_xstat)) + else if (WIFSIGNALED(p->p_xstat)) { siginfo->si_code = CLD_KILLED; - else + siginfo->si_status = WTERMSIG(p->p_xstat); + } else { siginfo->si_code = CLD_EXITED; + siginfo->si_status = WEXITSTATUS(p->p_xstat); + } siginfo->si_pid = p->p_pid; siginfo->si_uid = p->p_ucred->cr_uid; - siginfo->si_status = p->p_xstat; /* * The si_addr field would be useful additional * detail, but apparently the PC value may be lost >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201311151528.rAFFSCQ2079936>