char        mock_auth_nonce_str[MOCK_AUTH_NONCE_LEN * 2 + 1];
     const char *strftime_fmt = "%c";
     const char *progname;
 -   XLogSegNo   segno;
     char        xlogfilename[MAXFNAMELEN];
     int         c;
     int         i;
      WalSegSz = ControlFile->xlog_seg_size;
  
     if (!IsValidWalSegSize(WalSegSz))
 -       fprintf(stderr,
 -               _("WARNING: WAL segment size specified, %d bytes, is not a power of two between 1MB and 1GB.\n"
 -                 "The file is corrupt and the results below are untrustworthy.\n"),
 -               WalSegSz);
 +       printf(_("WARNING: invalid WAL segment size\n"
 +                "The WAL segment size stored in the file, %d bytes, is not a power of two\n"
 +                "between 1 MB and 1 GB.  The file is corrupt and the results below are\n"
 +                "untrustworthy.\n\n"),
 +              WalSegSz);
  
     /*
      * This slightly-chintzy coding will work as long as the control file
      /*
      * Calculate name of the WAL file containing the latest checkpoint's REDO
      * start point.
 +    *
 +    * A corrupted control file could report a WAL segment size of 0, and to
 +    * guard against division by zero, we need to treat that specially.
      */
 -   XLByteToSeg(ControlFile->checkPointCopy.redo, segno, WalSegSz);
 -   XLogFileName(xlogfilename, ControlFile->checkPointCopy.ThisTimeLineID,
 -                segno, WalSegSz);
 +   if (WalSegSz != 0)
 +   {
 +       XLogSegNo   segno;
 +
 +       XLByteToSeg(ControlFile->checkPointCopy.redo, segno, WalSegSz);
 +       XLogFileName(xlogfilename, ControlFile->checkPointCopy.ThisTimeLineID,
 +                    segno, WalSegSz);
 +   }
 +   else
 +       strcpy(xlogfilename, _("???"));
  
     /*
      * Format system_identifier and mock_authentication_nonce separately to
          use warnings;
  use PostgresNode;
  use TestLib;
 -use Test::More tests => 13;
 +use Test::More tests => 17;
  
  program_help_ok('pg_controldata');
  program_version_ok('pg_controldata');
   
  command_like([ 'pg_controldata', $node->data_dir ],
     qr/checkpoint/, 'pg_controldata produces output');
 +
 +
 +# check with a corrupted pg_control
 +
 +my $pg_control = $node->data_dir . '/global/pg_control';
 +my $size = (stat($pg_control))[7];
 +
 +open my $fh, '>', $pg_control or BAIL_OUT($!);
 +binmode $fh;
 +# fill file with zeros
 +print $fh pack("x[$size]");
 +close $fh;
 +
 +command_checks_all([ 'pg_controldata', $node->data_dir ],
 +                  0,
 +                  [ qr/WARNING: Calculated CRC checksum does not match value stored in file/,
 +                    qr/WARNING: invalid WAL segment size/ ],
 +                  [ qr/^$/ ],
 +                  'pg_controldata with corrupted pg_control');