Date: Tue, 20 Jun 2000 18:57:16 +0300 (EEST) From: netch@segfault.kiev.ua (Valentin Nechayev) To: FreeBSD-gnats-submit@freebsd.org Subject: kern/19402: Signals 127 and 128 cannot be detected normally in wait4() interface Message-ID: <200006201557.SWA63293@burka.carrier.kiev.ua>
next in thread | raw e-mail | index | archive | help
>Number: 19402 >Category: kern >Synopsis: Signals 127 and 128 cannot be detected in wait4() interface >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Tue Jun 20 09:00:01 PDT 2000 >Closed-Date: >Last-Modified: >Originator: Valentin Nechayev <netch@netch.kiev.ua> >Release: FreeBSD 4.0 >Organization: Kiev >Environment: FreeBSD 4.0; possibly, 5.0 also >Description: Syscall wait4() and libc routines wait3(), waitpid() return status of terminated/stopped process in "status" parameter passed by pointer in some encoded format. Standard header <sys/wait.h> provides macros for its decoding. Some of them are: #define _WSTATUS(x) (_W_INT(x) & 0177) #define _WSTOPPED 0177 /* _WSTATUS if process is stopped */ #define WIFSTOPPED(x) (_WSTATUS(x) == _WSTOPPED) #define WIFSIGNALED(x) (_WSTATUS(x) != _WSTOPPED && _WSTATUS(x) != 0) But FreeBSD 4 & 5 has signal with number 127, and terminating on this signal mixes mistakely with stopping. Stopping on signal 128 mixes with coredumping without signal. >How-To-Repeat: Compile two following test programs: === cut si.c === #include <sys/types.h> #include <unistd.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> int main( int argc, char *argv[] ) { int sig; sig = strtol( argv[1], NULL, 0 ); signal( sig, SIG_DFL ); kill( getpid(), sig ); printf( "si: trace: after kill\n" ); return 0; } === end cut === === cut sic.c === #include <sys/types.h> #include <sys/wait.h> #include <stdlib.h> #include <stdio.h> #include <string.h> int main( int argc, char *argv[] ) { int rr; pid_t cpid; #if 0 char bb[1000]; snprintf( bb, sizeof bb, "./si %s", argv[1] ); rr = system( bb ); #endif cpid = fork(); if( cpid == -1 ) { fprintf( stderr, "fork(): failed\n" ); return 2; } if( cpid == 0 ) execl( "./si", "./si", argv[1], NULL ); else waitpid( cpid, &rr, 0 ); printf( "rr==%d==0x%X\n", rr, rr ); printf( "Exited: %s\n", WIFEXITED(rr) ? "yes" : "no" ); printf( "Stopped: %s\n", WIFSTOPPED(rr) ? "yes" : "no" ); printf( "Signaled: %s\n", WIFSIGNALED(rr) ? "yes" : "no" ); printf( "Exit status: %d\n", WEXITSTATUS(rr) ); printf( "Stop sig: %d\n", WSTOPSIG(rr) ); printf( "Term sig: %d\n", WTERMSIG(rr) ); printf( "Coredumped: %s\n", WCOREDUMP(rr) ? "yes" : "no" ); return 0; } === end cut === Compile them: cc -o si si.c cc -o sic sic.c and run "sic 126", "sic 127" and "sic 128". Result print attached: === cut result log === netch@ox:~/tmp>./sic 126 rr==126==0x7E Exited: no Stopped: no Signaled: yes Exit status: 0 Stop sig: 0 Term sig: 126 Coredumped: no netch@ox:~/tmp>./sic 127 rr==127==0x7F Exited: no Stopped: yes Signaled: no Exit status: 0 Stop sig: 0 Term sig: 127 Coredumped: no netch@ox:~/tmp>./sic 128 rr==128==0x80 Exited: yes Stopped: no Signaled: no Exit status: 0 Stop sig: 0 Term sig: 0 Coredumped: yes === end cut === With signal 127, WIFSTOPPED() is true. With signal 128, WCOREDUMP() is true and WIFEXITED() is true. ;( Also another test: netch@ox:~/tmp>./si 127 [1]+ Stopped ./si 127 netch@ox:~/tmp>fg ./si 127 and in this case bash falls to infinite cycle on waitpid() with eating of all available CPU. Of course, this is ugly bash bug, but it is called by kernel interface inconsistency. Version of system on testing host: netch@ox:~>uname -mrs FreeBSD 4.0-STABLE i386 netch@ox:~>fgrep __FreeBSD_version /usr/include/sys/param.h #undef __FreeBSD_version #define __FreeBSD_version 400019 /* Master, propagated to newvers */ netch@ox:~> >Fix: As a quick-and-dirty fix, disable signals 127-128 at all (desrease value of _SIG_MAXSIG by 2, new value should be 126). As normal fix, change kernel interface (wait4() syscall). -- NVA >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200006201557.SWA63293>