bug-m4
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: AIX sysval failure


From: Gary V. Vaughan
Subject: Re: AIX sysval failure
Date: Thu, 26 Feb 2009 13:10:50 +0700

Hi Eric,

Diligently following your lead:

2009/2/26 Eric Blake <address@hidden>:
> Gary V. Vaughan <gary <at> gnu.org> writes:
>
>> > What is sysval after this run?
>> >
>> > $ echo 'changequote([,])syscmd([echo "meh" && kill -9 $$ ||
>> >    echo "oops: $?"])sysval' | ./src/m4
>>
>> Oh yeah.  D'uh, should've thought of that myself!
>>
>> % echo 'changequote([,])syscmd([echo "meh" && kill -9 $$ ||
>>    echo "oops: $?"])sysval' | ./src/m4
>> meh
>> 127
>
> What if you replace the || with ; in the syscmd?  Or how about:

Same deal.  As one would expect, the child process has been killed already
before execution reaches the "oops".

> echo 'changequote([,])syscmd([sh -c '\''kill -9 $$'\'';
>  st=$?; echo $st; exit $st])sysval' | ./src/m4

% echo 'changequote([,])syscmd([sh -c '\''kill -9 $$'\''; \
  st=$?; echo $st; exit $st])sysval' | ./src/m4
sh: 1118262 Killed
137
137

> Also, do you have anything like strace or truss, that can see what syscalls
> were in play during syscmd's use of system()?

AIX does have truss, but I couldn't find anything useful in the voluminous
output.  The full trace is smaller for the example program below though...
maybe you'll see something that escaped me?

> Maybe this slimmed down program is helpful as a debugging aid:
>
> $ cat foo.c
> #include <stdio.h>
> #include <stdlib.h>
> #include <errno.h>
> #include <unistd.h>
> #include <sys/wait.h>
>
> int main (int argc, char **argv)
> {
>  int r = system (argc == 1 ? "kill -9 $$" : argv[1]);
>  printf ("%04x %d\n", r, errno);
>  if (fork ())
>    {
>      wait (&r);
>      printf ("%04x %d\n", r, errno);
>    }
>  else
>    {
>      execlp ("sh", "sh", "-c",
>              argc == 1 ? "kill -9 $$" : argv[1], (char*) 0);
>    }
>  return 0;
> }
> $ ./foo false
> 0100 0
> 0100 0
> $ ./foo
> 0009 0
> 0009 0

% xlc -o foo foo.c
% ./foo false
0100 0
0100 0
% ./foo
ffffffff 0
90009 0
% truss -u:libc.a::system,fork,wait,waitpid,execlp,printf -f ./foo

Output Format: <pid>: {<childpid>:} <syscall>(<args>...) = <return value>

1118340: execve("./foo", 0x2FF22B70, 0x2000EB28)                 argc: 1
1118340: 1716323: _sigaction(2, 0x2FF22A60, 0x2FF22A70) = 0
1118340: 1716323: _sigaction(3, 0x2FF22A60, 0x2FF22A80) = 0
1118340: 1716323: sigprocmask(0, 0x2FF22A64, 0x2FF22A58)        = 0
1118340: 1716323: _sigaction(20, 0x2FF22A60, 0x2FF22A90)        = 0
1118340: 1716323: kfork()                               = 585844
585844: kfork()         (returning as child ...)        = 0
585844: _sigaction(2, 0x2FF22A70, 0x00000000)           = 0
585844: _sigaction(3, 0x2FF22A80, 0x00000000)           = 0
585844: _sigaction(20, 0x2FF22A90, 0x00000000)          = 0
585844: sigprocmask(2, 0x2FF22A58, 0x00000000)          = 0
585844: privcheck(910)                                  = 1
585844: execve("/usr/bin/sh", 0xF0315F28, 0x2FF22B9C)    argc: 3
... shell startup calls ...
585844: kioctl(2, 21522, 0x2FF22A08, 0x00000000)        Err#1  EPERM
585844: statx("/opt/build/m4-1.4.12.27-ccc137", 0x2FF22790, 176, 020) = 0
585844: statx(".", 0x2FF22840, 176, 020)                = 0
585844: _getpid()                                       = 585844
585844: _getppid()                                      = 1118340
585844: kill(585844, 9)                                 = 0
585844: *** process killed ***
1118340: 1716323: kwaitpid(0x2FF22A50, 585844, 4, 0x00000000,
0x00000000) = 585844
1118340: 1716323: _sigaction(2, 0x2FF22A70, 0x00000000) = 0
1118340: 1716323: _sigaction(3, 0x2FF22A80, 0x00000000) = 0
1118340: 1716323: _sigaction(20, 0x2FF22A90, 0x00000000)        = 0
1118340: 1716323: sigprocmask(2, 0x2FF22A58, 0x00000000)        = 0
1118340: 1716323: ->libc.a:printf(0x10000564, 0xffffffffffffffff, 0x0,
0xd0b2, 0x0, 0x267, 0x0, 0x0)
1118340: 1716323: kioctl(1, 22528, 0x00000000, 0x00000000) = 0
ffffffff 0
1118340: 1716323: kwrite(1, " f f f f f f f f   0\n", 11) = 11
1118340: 1716323: <-libc.a:printf() = b         0.000000
1118340: 1716323: ->libc.a:fork()
1118340: 1716323: kfork()                               = 585846
585846: kfork()         (returning as child ...)        = 0
585846: ->libc.a:execlp(0x10000570, 0x10000570, 0x10000574,
0x10000558, 0x0, 0x399, 0x0, 0x0)
1118340: 1716323: <-libc.a:fork() = 8f076               0.000000
1118340: 1716323: ->libc.a:wait(0x2ff22af0)
585846: execve("/home/gary/bin/sh", 0xF0315F28, 0x2FF22B9C) Err#2  ENOENT
585846: execve("/home/gary/bin/sh", 0xF0315F28, 0x2FF22B9C) Err#2  ENOENT
585846: execve("/opt/fsw/bin/sh", 0xF0315F28, 0x2FF22B9C) Err#2  ENOENT
585846: execve("/opt/tww/bin/sh", 0xF0315F28, 0x2FF22B9C) Err#2  ENOENT
585846: execve("/usr/vac/bin/sh", 0xF0315F28, 0x2FF22B9C) Err#2  ENOENT
585846: execve("/usr/vacpp/bin/sh", 0xF0315F28, 0x2FF22B9C) Err#2  ENOENT
585846: execve("/bin/sh", 0xF0315F28, 0x2FF22B9C)        argc: 3
... subshell startup calls ...
585846: _getpid()                                       = 585846
585846: _getppid()                                      = 1118340
585846: kill(585846, 9)                                 = 0
585846: *** process killed ***
1118340: 1716323: kwaitpid(0x2FF22AF0, -1, 4, 0x00000000, 0x00000000) = 585846
1118340: 1716323: <-libc.a:wait() = 8f076               0.000000
1118340: 1716323: ->libc.a:printf(0x10000564, 0x90009, 0x0, 0xd0b2,
0x0, 0x2ac, 0x0, 0x0)
90009 0
1118340: 1716323: kwrite(1, " 9 0 0 0 9   0\n", 8)      = 8
1118340: 1716323: <-libc.a:printf() = 8         0.000000
1118340: 1716323: kfcntl(1, F_GETFL, 0x2FF22FFC)                = 67110914
1118340: 1716323: kfcntl(2, F_GETFL, 0xF02DE418)                = 67110914
1118340: 1716323: _exit(0)

All the execed shells use the same inode:

% ls -1i /usr/bin/ksh /usr/bin/sh /bin/sh
 8775 /usr/bin/ksh
 8775 /usr/bin/sh
 8775 /bin/sh

> On my system, the lower 7 bits represent signals, the upper 8 represent normal
> return (on some platforms, this setup is swapped).  The intent of the m4 test
> is to find some portable way to cause sysval's child process to exit with a
> signal (since we document that sysval distinguishes signals from normal exit,
> similar to Solaris m4), hence the attempt to use 'kill -9 $$' since that is
> unblockable.  I'm starting to wonder if AIX system() is massaging the return
> value from wait(); maybe the gnulib 'execute' module is worthwhile.

There's definitely something odd going on, but I haven't found the magic
truss command to reveal it yet :(  If we can either fix the problem by
using gnulib execute, or fix gnulib execute to work around the problem then
using it is certainly a very good idea!

> Similar questions apply to popen() for esyscmd.

*pop*

(that was the sound of my brain overloading, with attendant escaping
blue smoke :)

Cheers,
    Gary
-- 
Email me:          address@hidden                        (\(\
Read my blog:      http://blog.azazil.net              ( o.O)
And my other blog: http://www.machaxor.net              (uu )o
...and my book:    http://sources.redhat.com/autobook  ("("_)




reply via email to

[Prev in Thread] Current Thread [Next in Thread]