Date: Fri, 16 Jan 2009 10:33:15 -0800 (PST) From: Nate Eldredge <neldredge@math.ucsd.edu> To: Garrett Cooper <yanefbsd@gmail.com> Cc: Thierry Herbelot <thierry.herbelot@free.fr>, freebsd-hackers@freebsd.org, Christoph Mallon <christoph.mallon@gmx.de> Subject: Re: Confused by segfault with legitimate call to strerror(3) on amd64 / sysctl (3) setting `odd' errno's Message-ID: <Pine.GSO.4.64.0901161023030.18030@zeno.ucsd.edu> In-Reply-To: <7d6fde3d0901161006r79f0cac4yf80c9c5079152b87@mail.gmail.com> References: <7d6fde3d0901160041n55466290l55f737d274a40895@mail.gmail.com> <49705FA2.2020605@gmx.de> <7d6fde3d0901160235o6aa1f096q11c5096b70f3577@mail.gmail.com> <200901161152.53478.thierry.herbelot@free.fr> <7d6fde3d0901161006r79f0cac4yf80c9c5079152b87@mail.gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
This message is in MIME format. The first part should be readable text, while the remaining parts are likely unreadable without MIME-aware tools. ---559023410-570397931-1232130795=:18030 Content-Type: TEXT/PLAIN; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: QUOTED-PRINTABLE On Fri, 16 Jan 2009, Garrett Cooper wrote: > On Fri, Jan 16, 2009 at 2:52 AM, Thierry Herbelot > <thierry.herbelot@free.fr> wrote: >> Le Friday 16 January 2009, Garrett Cooper a =E9crit : >>> On Fri, Jan 16, 2009 at 2:21 AM, Christoph Mallon >>> >>> #include <errno.h> >>> #include <stdio.h> >>> #include <sys/stat.h> >>> >>> int >>> main() >>> { >>> >>> struct stat sb; >>> >>> int o_errno; >>> >>> if (stat("/some/file/that/doesn't/exist", &sb) !=3D 0) { >>> o_errno =3D errno; >>> printf("Errno: %d\n", errno); >>> printf("%s\n", strerror(o_errno)); >>> } >>> >>> return 0; >>> >>> } >>> >> with this, it's better on an amd64/ RELENG_7 machine : >> >> % diff -ub badfile.c.ori badfile.c >> --- badfile.c.ori 2009-01-16 11:49:44.778991057 +0100 >> +++ badfile.c 2009-01-16 11:49:03.470465677 +0100 >> @@ -1,6 +1,7 @@ >> #include <errno.h> >> #include <stdio.h> >> #include <sys/stat.h> >> +#include <string.h> >> >> int >> main() >> >> Cheers >> >> TfH > > That's hilarious -- why does it pass though without issue on x86 though? > -Garrett As pointed out, when you don't have a declaration for strerror, it's=20 implicitly assumed to return `int'. This "feature" was widely used in the= =20 early days of C and so continues to be accepted by compilers, and gcc by=20 default doesn't warn about it. On x86, int and char * are the same size. So even though the compiler=20 thinks strerror is returning an int which is being passed to printf, the=20 code it generates is the same as for a char *. On amd64, int is 32 bits=20 but char * is 64. When the compiler thinks it's using int, it only keeps= =20 track of the lower 32 bits, and the upper 32 bits get zeroed. So the=20 pointer that printf receives has had its upper 32 bits zeroed, and no=20 longer points where it should. Hence segfault. Since running on amd64 I've seen a lot of bugs where people carelessly=20 assume (perhaps without noticing) that ints and pointers are practically=20 interchangeable, which works on x86 and the like but breaks on amd64.=20 Variadic functions are special offenders because the compiler can't do=20 much type checking. Pop quiz: which of the following statements is correct? #include <stdlib.h> #include <unistd.h> execl("/bin/sh", "/bin/sh", 0); execl("/bin/sh", "/bin/sh", NULL); --=20 Nate Eldredge neldredge@math.ucsd.edu ---559023410-570397931-1232130795=:18030--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.GSO.4.64.0901161023030.18030>