From owner-freebsd-hackers@FreeBSD.ORG Fri Jan 16 18:33:18 2009 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 0A2BC1065674 for ; Fri, 16 Jan 2009 18:33:18 +0000 (UTC) (envelope-from neldredge@math.ucsd.edu) Received: from euclid.ucsd.edu (euclid.ucsd.edu [132.239.145.52]) by mx1.freebsd.org (Postfix) with ESMTP id DC4228FC1E for ; Fri, 16 Jan 2009 18:33:17 +0000 (UTC) (envelope-from neldredge@math.ucsd.edu) Received: from zeno.ucsd.edu (zeno.ucsd.edu [132.239.145.22]) by euclid.ucsd.edu (8.11.7p3+Sun/8.11.7) with ESMTP id n0GIXFo29370; Fri, 16 Jan 2009 10:33:15 -0800 (PST) Received: from localhost (neldredg@localhost) by zeno.ucsd.edu (8.11.7p3+Sun/8.11.7) with ESMTP id n0GIXFU21412; Fri, 16 Jan 2009 10:33:15 -0800 (PST) X-Authentication-Warning: zeno.ucsd.edu: neldredg owned process doing -bs Date: Fri, 16 Jan 2009 10:33:15 -0800 (PST) From: Nate Eldredge X-X-Sender: neldredg@zeno.ucsd.edu To: Garrett Cooper In-Reply-To: <7d6fde3d0901161006r79f0cac4yf80c9c5079152b87@mail.gmail.com> Message-ID: References: <7d6fde3d0901160041n55466290l55f737d274a40895@mail.gmail.com> <49705FA2.2020605@gmx.de> <7d6fde3d0901160235o6aa1f096q11c5096b70f3577@mail.gmail.com> <200901161152.53478.thierry.herbelot@free.fr> <7d6fde3d0901161006r79f0cac4yf80c9c5079152b87@mail.gmail.com> MIME-Version: 1.0 Content-Type: MULTIPART/MIXED; BOUNDARY="-559023410-570397931-1232130795=:18030" Cc: Thierry Herbelot , freebsd-hackers@freebsd.org, Christoph Mallon Subject: Re: Confused by segfault with legitimate call to strerror(3) on amd64 / sysctl (3) setting `odd' errno's X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 16 Jan 2009 18:33:18 -0000 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 > wrote: >> Le Friday 16 January 2009, Garrett Cooper a =E9crit : >>> On Fri, Jan 16, 2009 at 2:21 AM, Christoph Mallon >>> >>> #include >>> #include >>> #include >>> >>> 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 >> #include >> #include >> +#include >> >> 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 #include execl("/bin/sh", "/bin/sh", 0); execl("/bin/sh", "/bin/sh", NULL); --=20 Nate Eldredge neldredge@math.ucsd.edu ---559023410-570397931-1232130795=:18030--