What you have to look for on 64 bit

Ken Brown kbrown@cornell.edu
Tue Mar 19 17:12:00 GMT 2013


On 3/19/2013 6:48 AM, Corinna Vinschen wrote:
> Hi guys,
>
>
> it just occured to me that it might be helpful to report a typical 64
> bit porting bug we observed yesterday, while testing the sigdelayed
> patch.
>
> Kai was going to run the gas testsuite which requires dejagnu and
> expect, but expect simply crashed.  After a bit of debugging it
> turned out that expect was calling the openpty function, like so:
>
>    char *master, *slave,*name;
>    openpty (master, slave, name, 0, 0);
>
> The last two parameters to openpty are pointers, just like the first
> three.  However, the constant 0 is int by default.  int is 32 bit, but
> pointers are 64 bit on x86_64.  This would have been no problem, if
> expect had included the pty.h header which provides a prototype for
> openpty.  GCC would have known to extend the 0 constants to 64 bit in
> this case.  Alas, expect did not include pty.h and so the 0 were not 64
> bit extended, but given as 32 bit parameter to openpty.  Since all
> parameters take 64 bit slots, the upper 32 bit of the parameters were
> undefined.  Instead of NULL pointers, openpty got pointers with just
> the lower 32 bit guaranteed to be 0.
>
> Another simple example:  Try `printf ("%s\n", strerror (EINVAL));'
> without including string.h.  Same thing as above.  The missing prototype
> for strerror leads gcc to think it's a function returning int.  No
> problem on 32 bit where sizeof(int)==sizeof(char*), but on 64 bit...
>
> <annoying lecturing>
>
> Bottom line is, when building packages for 64 bit, make sure to
> switch on warnings for missing prototypes and if you get these
> warnings, make sure to include the right headers to get the prototype.
> Otherwise, SEGV ensues.
>
> </annoying lecturing>

I tried your printf example, and as you said, it compiled but crashed. 
But gcc didn't report the missing prototype, even though I compiled with 
`gcc -Wmissing-prototypes'.  Did I do something wrong?  Here's the 
source file:

#include <stdio.h>
#include <errno.h>
int
main ()
{
   printf ("%s\n", strerror (EINVAL));
}

Ken



More information about the Cygwin-developers mailing list