Bug #20145 perror segfault when call it with error nr
Submitted: 30 May 2006 11:09 Modified: 15 Aug 2006 3:07
Reporter: Markus Heinze Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Command-line Clients Severity:S3 (Non-critical)
Version:5.0.21 OS:Solaris (Solaris 8)
Assigned to: Magnus Blåudd CPU Architecture:Any

[30 May 2006 11:09] Markus Heinze
Description:
When built from source the tool extra/perror it segfaults if i run ./perror <errornr>.

gcc -version:
gcc (GCC) 3.3.2
Copyright (C) 2003 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

builded with:
#!/bin/bash

. platform.sh

export CXX=gcc
#export CFLAGS="-O3 -DUSE_OLD_FUNCTIONS"
export CFLAGS="-DUSE_OLD_FUNCTIONS"
export CXXFLAGS=$CFLAGS
#export CXXFLAGS="$CFLAGS -felide-constructors -fno-exceptions -fno-rtti"
#echo $CXXFLAGS
cd mysql

./configure \
--prefix=/usr/local \
--sysconfdir=/etc \
--localstatedir=/JobsAdverts/SqlServer/var \
--enable-thread-safe-client \
--enable-assembler \
--enable-static \
--with-raid \
--with-mysql-user=mysql \
--without-debug \
--without-docs \
--without-bench \
--with-extra-charsets=complex \
--with-innodb \

$MAKE -j 4 &&
cd mysql-test && ./mysql-test-run --force

cd ..

How to repeat:
run perror with errnr e.g. ./perror 150

Suggested fix:
I have outcommented the NETWARE initialization and it works for me now.
I should be better written between  #ifdef /  #endif  tags.

--- perror.c.orig       Wed Apr 26 20:31:09 2006
+++ perror.c    Wed May  3 13:58:29 2006
@@ -218,10 +218,10 @@
       On some system, like NETWARE, strerror(unknown_error) returns a
       string 'Unknown Error'.  To avoid printing it we try to find the
       error string by asking for an impossible big error message.
-    */
+    
     msg= strerror(10000);
 
-    /*
+   
       Allocate a buffer for unknown_error since strerror always returns
       the same pointer on some platforms such as Windows
     */
[13 Jun 2006 16:11] Valeriy Kravchuk
Thank you for a problem report. Can you try to repeat with MySQL's binaries? 

The problem is that we do not really use gcc for builds on platforms with "native" C compilers, so gcc environment on any our Solaris boxes is not "clear enough" to repeat this (although, I'll try to build with gcc if official binaries will not demonstrate the behaviour described). I was also unable to repeat this on Linux with gcc 3.3.5, so it can be a compiler-related problem as well.
[14 Jun 2006 9:04] Markus Heinze
I have tried the binary version (mysql-standard-5.0.22-solaris8-sparc-64bit.pkg.gz) for Solaris 8 and get the same problem.

./perror 150
Segmentation Fault (core dumped)

./perror -v
./perror Ver 2.10, for sun-solaris2.8 (sparc)
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to modify and redistribute it under the GPL license

Print a description for a system error code or an error code from
a MyISAM/ISAM/BDB table handler.
If you want to get the error for a negative error code, you should use
-- before the first error code to tell perror that there was no more options.

Usage: ./perror [OPTIONS] [ERRORCODE [ERRORCODE...]]
  -?, --help          Displays this help and exits.
  -I, --info          Synonym for --help.
  -s, --silent        Only print the error message.
  -v, --verbose       Print error code and message (default).
  -V, --version       Displays version information and exits.

Variables (--variable-name=value)
and boolean options {FALSE|TRUE}  Value (after reading options)
--------------------------------- -----------------------------
verbose                           TRUE
[29 Jun 2006 10:26] Sveta Smirnova
Verified as reporter described:

mysqldev@sunfire100a:~/sveta/mysql-standard-5.0.22-solaris8-sparc-64bit> uname -a
SunOS sunfire100a 5.8 Generic_117350-25 sun4u sparc SUNW,UltraAX-i2
mysqldev@sunfire100a:~/sveta/mysql-standard-5.0.22-solaris8-sparc-64bit> bin/perror 150
Segmentation Fault (core dumped)
mysqldev@sunfire100a:~/sveta/mysql-standard-5.0.22-solaris8-sparc-64bit> bin/perror -v
bin/perror Ver 2.10, for sun-solaris2.8 (sparc)
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to modify and redistribute it under the GPL license

Print a description for a system error code or an error code from
a MyISAM/ISAM/BDB table handler.
If you want to get the error for a negative error code, you should use
-- before the first error code to tell perror that there was no more options.

Usage: bin/perror [OPTIONS] [ERRORCODE [ERRORCODE...]]
  -?, --help          Displays this help and exits.
  -I, --info          Synonym for --help.
  -s, --silent        Only print the error message.
  -v, --verbose       Print error code and message (default).
  -V, --version       Displays version information and exits.

Variables (--variable-name=value)
and boolean options {FALSE|TRUE}  Value (after reading options)
--------------------------------- -----------------------------
verbose                           TRUE
[29 Jun 2006 10:36] Sveta Smirnova
I can not repeat this error on Solaris9 SPARC and Solaris10 x86.
[29 Jun 2006 10:43] Sveta Smirnova
We have duplicate bug #20731
[4 Jul 2006 13:18] Steven Xie
I didn't find this one last time.
 Please ignore the new bug report.
 It's the same bug.
[4 Jul 2006 13:24] Steven Xie
For solaris 8/7/6
strerror
RETURN VALUES
     The strerror() function returns NULL if  errnum  is  out-of-
     range.

For solaris 9/10
RETURN VALUES
     Upon successful completion, strerror() returns a pointer  to
     the  generated  message string. Otherwise, it sets errno and
     returns a pointer to an error message string. It returns the
     string  "Unknown  error"  if  errnum  is  not  a valid error
     number.

That's why you couldn't reproduce it on solaris 9/10.
It's a bug.

BTW, 
It's not safe to have code like below 

 /*
      On some system, like NETWARE, strerror(unknown_error) returns a
      string 'Unknown Error'.  To avoid printing it we try to find the
      error string by asking for an impossible big error message.
    */
    msg= strerror(10000);  
   /* msg could be set to NULL under some platforms
    * then strlen would core .
    */

                                                                       
                                                                        
            
    /*
      Allocate a buffer for unknown_error since strerror always
returns
      the same pointer on some platforms such as Windows
    */
    unknown_error= malloc(strlen(msg)+1);

Suggested fix:
/*
      On some system, like NETWARE, strerror(unknown_error) returns a
      string 'Unknown Error'.  To avoid printing it we try to find the
      error string by asking for an impossible big error message.
    */
    msg= strerror(10000);  
   /* msg could be set to NULL on some platforms
    *  e.g solaris 2.8
    */
     if (NULL==msg)
         msg="Unknown  Error";

                                                                       
                                                                        
            
    /*
      Allocate a buffer for unknown_error since strerror always
returns
      the same pointer on some platforms such as Windows
    */
    unknown_error= malloc(strlen(msg)+1);
[24 Jul 2006 16:10] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/9505
[3 Aug 2006 16:47] Magnus Blåudd
Pushed to 5.0.25
[3 Aug 2006 17:22] Paul DuBois
Noted in 5.0.25 changelog.

perror crashed on Solaris due to NULL return value of strerror()
system call.
[14 Aug 2006 20:51] Konstantin Osipov
Merged into 5.1.12
[15 Aug 2006 3:07] Paul DuBois
Noted in 5.1.12 changelog.
[11 Jan 2007 13:46] Sveta Smirnova
There is similar bug #25344