regression script/makefile exit failure

Started by Andrew Dunstanabout 21 years ago8 messages
#1Andrew Dunstan
andrew@dunslane.net

I have seen several cases where either pg_regress appears not to exit
with the expected non-zero exit status or "make check" does not
apparently exit with the expected non-zero status.

In particular, I've seen it on cygwin, windows, and have at least a
suspicion of it happening on FreeBSD.

The apparently offending code is this:

message "initializing database system"
[ "$debug" = yes ] && initdb_options='--debug'
"$bindir/initdb" -D "$PGDATA" -L "$datadir" --noclean
$initdb_options >"$LOGDIR/initdb.log" 2>&1

if [ $? -ne 0 ]
then
echo
echo "$me: initdb failed"
echo "Examine $LOGDIR/initdb.log for the reason."
echo
(exit 2); exit
fi

and it's called from this makefile target:

check: all
-rm -rf ./testtablespace
mkdir ./testtablespace
$(SHELL) ./pg_regress --temp-install
--top-builddir=$(top_builddir) --schedule=$(srcdir)/parallel_schedule
--multibyte=$(MULTIBYTE) $(MAXCONNOPT)

The practical consequence of this is that instead of failing at this
stage, the buildfarm script continues on until it somewhat inexplicably
fails at the initdb stage.

Now, perhaps I'm calling it wrong, but I don't think so. The relevant
perl code is this:

my @makeout = `cd $pgsql/src/test/regress && $make check 2>&1`;
my $status = $? >>8;

which idiom seems to work as expected everywhere else quite happily. And
in fact I've seen "make check" fail as expected on other failure paths
(such as not matching the expected result.)

Anyone have any penetrating thoughts?

cheers

andrew

#2Andrew Dunstan
andrew@dunslane.net
In reply to: Andrew Dunstan (#1)
Re: regression script/makefile exit failure

Further investigation has shown that the exit/trap idiom used in
pg_regress.sh is less than 100% portable.

The following shell script has been seen to produce incorrect output on
both Cygwin and FreeBSD:

#!/bin/sh

trap '
st=$?
echo status = $st
exit $st
' 0

(exit 9); exit

I'm not sure how we get a portable solution (other than maybe converting
the shell script to perl).

cheers

andrew

I wrote:

Show quoted text

I have seen several cases where either pg_regress appears not to exit
with the expected non-zero exit status or "make check" does not
apparently exit with the expected non-zero status.

In particular, I've seen it on cygwin, windows, and have at least a
suspicion of it happening on FreeBSD.

The apparently offending code is this:

message "initializing database system"
[ "$debug" = yes ] && initdb_options='--debug'
"$bindir/initdb" -D "$PGDATA" -L "$datadir" --noclean
$initdb_options >"$LOGDIR/initdb.log" 2>&1

if [ $? -ne 0 ]
then
echo
echo "$me: initdb failed"
echo "Examine $LOGDIR/initdb.log for the reason."
echo
(exit 2); exit
fi

and it's called from this makefile target:

check: all
-rm -rf ./testtablespace
mkdir ./testtablespace
$(SHELL) ./pg_regress --temp-install
--top-builddir=$(top_builddir) --schedule=$(srcdir)/parallel_schedule
--multibyte=$(MULTIBYTE) $(MAXCONNOPT)

The practical consequence of this is that instead of failing at this
stage, the buildfarm script continues on until it somewhat
inexplicably fails at the initdb stage.

Now, perhaps I'm calling it wrong, but I don't think so. The relevant
perl code is this:

my @makeout = `cd $pgsql/src/test/regress && $make check 2>&1`;
my $status = $? >>8;

which idiom seems to work as expected everywhere else quite happily.
And in fact I've seen "make check" fail as expected on other failure
paths (such as not matching the expected result.)

Anyone have any penetrating thoughts?

cheers

andrew

#3Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andrew Dunstan (#2)
Re: regression script/makefile exit failure

Andrew Dunstan <andrew@dunslane.net> writes:

Further investigation has shown that the exit/trap idiom used in
pg_regress.sh is less than 100% portable.
The following shell script has been seen to produce incorrect output on
both Cygwin and FreeBSD:

This is distinctly less than credible. If it were true, we'd have been
seeing regression failures on FreeBSD for years. The script has looked
like that at least back to 7.1 ...

regards, tom lane

#4Andrew Dunstan
andrew@dunslane.net
In reply to: Tom Lane (#3)
Re: regression script/makefile exit failure

Tom Lane said:

Andrew Dunstan <andrew@dunslane.net> writes:

Further investigation has shown that the exit/trap idiom used in
pg_regress.sh is less than 100% portable.
The following shell script has been seen to produce incorrect output
on both Cygwin and FreeBSD:

This is distinctly less than credible. If it were true, we'd have been
seeing regression failures on FreeBSD for years. The script has looked
like that at least back to 7.1 ...

I think you possibly misunderstand. It's not that the trap handler doesn't
get called - it's that it doesn't get the correct $?. The only symptom of
incorrectness is that pg_regress would exit with a status of 0 rather than 2
or whatever it should be. DarcyB ran that test script for me yesterday on
his FreeBSD-6 box (buildfarm's herring) and it produced "status = 0" rather
than the expected "status = 9". I would not expect anyone to have noticed
this behaviour unless they were testing the exit status of "make check".

cheers

andrew

#5Peter Eisentraut
peter_e@gmx.net
In reply to: Andrew Dunstan (#2)
Re: regression script/makefile exit failure

Andrew Dunstan wrote:

Further investigation has shown that the exit/trap idiom used in
pg_regress.sh is less than 100% portable.

The following shell script has been seen to produce incorrect output
on both Cygwin and FreeBSD:

#!/bin/sh

trap '
st=$?
echo status = $st
exit $st
' 0

(exit 9); exit

I seem to recall that there is a bug in the FreeBSD shell with line
breaks in traps. Try changing the above to

trap 'st=$?; echo status = $st; exit $st' 0

--
Peter Eisentraut
http://developer.postgresql.org/~petere/

#6Andrew Dunstan
andrew@dunslane.net
In reply to: Peter Eisentraut (#5)
Re: regression script/makefile exit failure

Peter Eisentraut wrote:

Andrew Dunstan wrote:

Further investigation has shown that the exit/trap idiom used in
pg_regress.sh is less than 100% portable.

The following shell script has been seen to produce incorrect output
on both Cygwin and FreeBSD:

#!/bin/sh

trap '
st=$?
echo status = $st
exit $st
' 0

(exit 9); exit

I seem to recall that there is a bug in the FreeBSD shell with line
breaks in traps. Try changing the above to

trap 'st=$?; echo status = $st; exit $st' 0

Thankyou Peter! I'd never have guessed something so obscure!

I have confirmed that this is the problem, and ascertained that the
Cygwin shell exhibits the same behaviour.

I will submit a patch for pg_regress.sh shortly (after a little testing
using buildfarm).

cheers

andrew

#7Andrew Dunstan
andrew@dunslane.net
In reply to: Andrew Dunstan (#6)
1 attachment(s)
Re: [HACKERS] regression script/makefile exit failure

Andrew Dunstan wrote:

Peter Eisentraut wrote:

I seem to recall that there is a bug in the FreeBSD shell with line
breaks in traps. Try changing the above to

trap 'st=$?; echo status = $st; exit $st' 0

Thankyou Peter! I'd never have guessed something so obscure!

I have confirmed that this is the problem, and ascertained that the
Cygwin shell exhibits the same behaviour.

I will submit a patch for pg_regress.sh shortly (after a little
testing using buildfarm).

Attached patch has been tested on Cygwin and found to work as expected
when initdb fails during make check - I don't have access to a FreeBSD
machine to do a test buildfarm run.

cheers

andrew

Attachments:

trap2.patchtext/x-patch; name=trap2.patchDownload
Index: src/test/regress/pg_regress.sh
===================================================================
RCS file: /home/cvsmirror/pgsql/src/test/regress/pg_regress.sh,v
retrieving revision 1.50
diff -c -r1.50 pg_regress.sh
*** src/test/regress/pg_regress.sh	17 Nov 2004 18:06:04 -0000	1.50
--- src/test/regress/pg_regress.sh	11 Dec 2004 21:27:40 -0000
***************
*** 238,255 ****
  # with the result of the last shell command before the `exit'.  Hence
  # we have to write `(exit x); exit' below this point.
  
! trap '
!     savestatus=$?
      if [ -n "$postmaster_pid" ]; then
          kill -2 "$postmaster_pid"
          wait "$postmaster_pid"
          unset postmaster_pid
      fi
      rm -f "$TMPFILE" && exit $savestatus
! ' 0
  
! trap '
!     savestatus=$?
      echo; echo "caught signal"
      if [ -n "$postmaster_pid" ]; then
          echo "signalling fast shutdown to postmaster with pid $postmaster_pid"
--- 238,257 ----
  # with the result of the last shell command before the `exit'.  Hence
  # we have to write `(exit x); exit' below this point.
  
! exit_trap(){ 
!     savestatus=$1
      if [ -n "$postmaster_pid" ]; then
          kill -2 "$postmaster_pid"
          wait "$postmaster_pid"
          unset postmaster_pid
      fi
      rm -f "$TMPFILE" && exit $savestatus
! }
  
! trap 'exit_trap $?' 0
! 
! sig_trap() {
!     savestatus=$1
      echo; echo "caught signal"
      if [ -n "$postmaster_pid" ]; then
          echo "signalling fast shutdown to postmaster with pid $postmaster_pid"
***************
*** 258,264 ****
          unset postmaster_pid
      fi
      (exit $savestatus); exit
! ' 1 2 13 15
  
  
  
--- 260,268 ----
          unset postmaster_pid
      fi
      (exit $savestatus); exit
! }
! 
! trap 'sig_trap $?' 1 2 13 15
  
  
  
#8Peter Eisentraut
peter_e@gmx.net
In reply to: Andrew Dunstan (#7)
Re: [HACKERS] regression script/makefile exit failure

Andrew Dunstan wrote:

Attached patch has been tested on Cygwin and found to work as
expected when initdb fails during make check - I don't have access to
a FreeBSD machine to do a test buildfarm run.

Patch installed.

--
Peter Eisentraut
http://developer.postgresql.org/~petere/