Date: Tue, 13 Mar 2007 14:15:38 +0100 From: Max Laier <max@love2party.net> To: freebsd-current@freebsd.org Subject: Re: Bad gcc -O optimization cause core dump. What to do? Message-ID: <200703131415.45709.max@love2party.net> In-Reply-To: <20070313123717.GU58523@codelabs.ru> References: <20070313121106.GA96293@nagual.pp.ru> <20070313123717.GU58523@codelabs.ru>
next in thread | previous in thread | raw e-mail | index | archive | help
--nextPart2353553.gtTboZbrzb
Content-Type: text/plain;
charset="koi8-r"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline
On Tuesday 13 March 2007 13:37, Eygene Ryabinkin wrote:
> Andrey, good day.
>
> > It calls "puts(NULL)" with core dump.
> > It means "printf("%s\n", NULL)" is overoptimized.
> > BTW, things like "printf("1%s\n", NULL)" are not overoptimized.
>
> Yes, it is in the gcc/builtins.c::expand_builtin_printf(). Currently
> it only handles "%s" and "%c".
>
> > Any ideas? Is it right or needs to be fixed?
>
> It is definitely not right, since it produces the bad code.
> And there are no compilation-time checks that can say for
> sure will the argument for the "%s" be NULL:
This is simply a programming error. Just because the function is called=20
printf doesn't make it right. It's nice that the libc's printf does all=20
these neat tricks, but it's also expensive (See the link I posted=20
earlier). According to the printf(3) manpage:
s The char * argument is expected to be a pointer to an array of
character type (pointer to a string). Characters from the array
are written up to (but not including) a terminating NUL charac-
ter; if a precision is specified, no more than the number speci-
fied are written. If a precision is given, no null character
need be present; if the precision is not specified, or is greater
than the size of the array, the array must contain a terminating
NUL character.
And I fail to see how "NULL" is a valid pointer to an array of character=20
type. This is C after all.
> -----
> $ cat 1.c
> #include <stdio.h>
>
> int main(void)
> {
> void *ptr =3D NULL;
> func(ptr);
> }
>
> int func(void *ptr)
> {
> printf("%s\n", ptr);
> }
>
> :: rea@codelabs : 15:31:43 : ~/xlam
>
> $ cat 1.s
> .file "1.c"
> .text
> .p2align 2,,3
> .globl main
> .type main, @function
> main:
> pushl %ebp
> movl %esp, %ebp
> subl $8, %esp
> andl $-16, %esp
> subl $28, %esp
> pushl $0
> call func
> leave
> ret
> .size main, .-main
> .p2align 2,,3
> .globl func
> .type func, @function
> func:
> pushl %ebp
> movl %esp, %ebp
> subl $20, %esp
> pushl 8(%ebp)
> call puts
> leave
> ret
> .size func, .-func
> -----
> The possible way to proceed with this optimization is to have the
> 'puts', but to enable runtime check for the NULL value.
>
> I see the following definition for the fn_puts in builtins.def:
> -----
> DEF_EXT_LIB_BUILTIN (BUILT_IN_PUTS_UNLOCKED, "puts_unlocked",
> BT_FN_INT_CONST_STRING, ATTR_NOTHROW_NONNULL_1) -----
> The ATTR_NOTHROW_NONNULL_1 makes me think that not all is lost and
> something can be done with the NULL pointer. I am not very familiar
> with gcc internals, but I will try to see if something can be changed.
=2D-=20
/"\ Best regards, | mlaier@freebsd.org
\ / Max Laier | ICQ #67774661
X http://pf4freebsd.love2party.net/ | mlaier@EFnet
/ \ ASCII Ribbon Campaign | Against HTML Mail and News
--nextPart2353553.gtTboZbrzb
Content-Type: application/pgp-signature
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (FreeBSD)
iD8DBQBF9qQBXyyEoT62BG0RAqONAJwOCMP+nq0RW+AzM/dr2dvZltMc0wCbBIpF
eqzpU0iXc9xBu6h9qPJyuT8=
=vBHA
-----END PGP SIGNATURE-----
--nextPart2353553.gtTboZbrzb--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200703131415.45709.max>
