Skip site navigation (1)Skip section navigation (2)
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>