Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

why does ignoring sigCHLD corrupt return value from system()?

by fiberhalo (Acolyte)
on Nov 05, 2003 at 00:15 UTC ( [id://304587]=perlquestion: print w/replies, xml ) Need Help??

fiberhalo has asked for the wisdom of the Perl Monks concerning the following question:

Why is it that when the sigCHLD signal is ignored, system() always returns -1?

-------------------- prog1.pl -----------------

#!/usr/bin/perl $SIG{'CHLD'} = 'IGNORE'; system('prog2.pl'); print "return value is ", $?>>8, "\n";
-------------------- prog2.pl ------------------
#!/usr/bin/perl exit 5;

If $SIG{'CHLD'} = 'IGNORE' is commented out, the return value is 5, which is what I expect. If it is left in, the return value is -1.

Is ignoring sigCHLD not recommended when using system?

I tested this on Linux, FreeBSD and Solaris with two versions of perl, all with the same results, so I assume this is something that is not really a bug. I've just never run across this before, and am looking for some insight.

20031105 Edit by Corion: Added CODE tags

Replies are listed 'Best First'.
Re: why does ignoring sigCHLD corrupt return value from system()?
by ehdonhon (Curate) on Nov 05, 2003 at 00:56 UTC

    There was some revisions on $SIG{CHLD} = 'IGNORE' that went into Perl 5.8.1, I believe. The short of it was that on some operating systems prior to 5.8.1, doing a SIG{CHLD} = 'IGNORE' could cause Perl to wait() for the forked child process twice and cause an infinite hang.

    If you are using something prior to 5.8.1, you might be seeing another symptom of the same problem. If you are using post-5.8.1, it could be that the patch broke something else.

    If you are the most recent version of Perl, it sounds like something you might want to submit a perlbug for. When you do, you might want to refer to bug # 18849

Re: why does ignoring sigCHLD corrupt return value from system()?
by sauoq (Abbot) on Nov 05, 2003 at 01:00 UTC

    I can reproduce this with 5.6.1 and 5.005_02 on Solaris 7. And with 5.8.0, 5.6.1, and 5.005_03 on Solaris 8.

    But I can't with 5.8.0 on Linux 2.4.18 (libc-2.2.93).

    -sauoq
    "My two cents aren't worth a dime.";
    
      Tested on Linux:
      • RH7.2, i386, perl 5.6.1, kernel 2.4.20, glibc 2.2.4: I get the expected result, ie -1 if system() fails and 5 if prog2.pl is run, independently of how sigCHILD is handled.
      • RH9a, i386, perl 5.8.0, kernel 2.4.20, glibc 2.3.2: when prog2.pl get executed, ignoring sigCHILD returns -1 instead of 5
      It definitely looks like a bug.
Re: why does ignoring sigCHLD corrupt return value from system()?
by TheHobbit (Pilgrim) on Nov 05, 2003 at 01:12 UTC

    Hi,
    There is an error in your code: you wrote system("prog2.pl") which does not invoke prog2.pl unless you have '.' (the current directory) in your PATH (which should be avoided).

    By replacing your instruction with system("./prog2.pl") I get a return code of 5 both with and without SIGCHLD ignored. Just as I expected.

    I expected this result because perl system emulates C system(3), and the man page of the latter states that:

    During execution of the command, SIGCHLD will be blocked, and SIGINT and SIGQUIT will be ignored.

    That is to say: system install its own SIGCHLD handler, which is needed exactly for capturing the exit status.

    I join Abigail-II in asking which version of perl, operating system and kernel are you using.

    By the way, why should ignoring SIGCHLD be recommended when using system? Never heard that...

    Hoping this helps


    Leo TheHobbit
      By replacing your instruction with system("./prog2.pl") I get a return code of 5 both with and without SIGCHLD ignored.

      But what did you get before you made that replacement? I'm guessing -1 in both cases and that your platform just isn't one of the ones that exhibits this.

      By the way, why should ignoring SIGCHLD be recommended when using system? Never heard that...

      I don't think that such a "recommendation" is suggested by the original post. I doubt he was ignoring SIGCHLD because he was using system(); I'd bet he just ran into this in a program that happened to do both. So, the question is: must we recommend never ignoring SIGCHLD when using system()?

      -sauoq
      "My two cents aren't worth a dime.";
      

        Hi,
        The fact that $SIG{CHLD} is set to wichever value the user chose must not change the behavior of system as stated in perlfunc, expecially where it states that:

        Does exactly the same thing as "exec LIST", except that a fork is done first, and the parent process waits for the child process to complete.

        The parent process needs to intercept SIGCHLD in order to wait(2) for the child process to complete.

        As I stated above, this implies that the value of $SIG{CHLD} must be localized to same value during the execution of system, and so the user value of it outside that execution is (or shuld be) irrelevant.

        Just my 5 (euro) cents.


        Leo TheHobbit
      Thanks everyone for the assistance/suggestions. This isn't a major issue for me or anything. I just happened to notice this when I added a system() to an existing program that already ignored sigCHLD. I have a workaround -- in fact, I think the reason that sigCHLD was ignored was that there used to be a fork() call, but now that's gone. I'm no longer ignoring the signal, so it's not a problem for now.

      I just recompiled a new version of 5.8.1 on my linux box and it still exhibits the same behavior. Oh, and I changed the parameter to system() to be './prog2.pl' with the same results. It looks like this account has a 'dot' in the $PATH. (bad, I know)

      Here are the versions that I have tested:

      linux 2.4.20-20.9 kernel (from RedHat9)
      tested with both perl v5.8.0 and v5.8.1
      using glibc 2.3.2 (glibc-2.3.2-27.9)

      sun 5.8 Generic_108528-17 sun4u sparc SUNW, UltraSPARC-IIi-cEngine
      perl v5.6.1
      not sure how to tell the C library version on sun

      FreeBSD 4.8-RELEASE
      perl version 5.005_03
      not sure how to tell the C library on FreeBSD

      If you guys think I should submit a bug report, I'll definitely do that.

      I haven't tested it, but I assume another workaround if someone really needed it would be to do the waitpid() inside of a reaper subroutine construct.

        The following piece of code examines the problem a bit further, along the guidelines of perlport:
        #!/usr/bin/perl use POSIX; if(@ARGV){ $SIG{'CHLD'} = 'IGNORE'; } system('./prog2.pl'); $status=$?; if(WIFEXITED($status)){ print "prog2.pl exited normally, returning ", WEXITSTATUS($status), "\n"; }elsif(WIFSIGNALED($status)){ print "prog2.pl was terminated with signal ", WTERMSIG($status), "\n"; }elsif(WIFSTOPPED($status)){ print "prog2.pl is stopped for signal ", WSTOPSIG($status), "\n"; }else{ print "can't understand what happened to prog2.pl; ", "status is ",$status,"\n"; }

        When I ran it under perl 5.8.0 (on i386 linux, kernel 2.4.20, glibc 2.3.2), I got the following results:
        #./prog1.pl
        prog2.pl exited normally, returning 5
        #./prog1.pl ignore
        prog2.pl was terminated with signal 127
        
        Interesting enough, no POSIX signal has number 127, AFAIK... something is not working here.
        Ant9000
        Yes, please do submit a bug report, using perlbug. Perlbug will include the output of 'perl -V', and among this output is the C library version number. Without a bug report, the issue is unlikely to get fixed, unless you send in a patch yourself.

        I'm not able to reproduce this problem using Linux, kernel 2.4.18-something (for various somethings), glibc 2.2.5, and Perl versions 5.005 .. 5.9.0.

        Abigail

Re: why does ignoring sigCHLD corrupt return value from system()?
by Abigail-II (Bishop) on Nov 05, 2003 at 00:24 UTC
    I can't reproduce that with Linux, both with the signal being ignored and not ignored. What versions of Perl are you using, what kernel are you running, and which C library are you using?

    Abigail

Re: why does ignoring sigCHLD corrupt return value from system()?
by bfdi533 (Friar) on Nov 05, 2003 at 19:59 UTC

    I have not been able to duplicate this "error".

    I have tested this on Gentoo Linux (kernel 2.4.20, glibc 2.3.2) with Perl 5.8.0 and it returns 5 as intended.

    Ed

      I ran into this on Gentoo with perl-5.20.2 with ithreads useflag enabled. Recompiling without ithreads (that is the default) fixed the problem.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://304587]
Approved by Roger
Front-paged by ehdonhon
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (4)
As of 2024-03-29 00:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found