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>