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
[-- Attachment #1 --]
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
printf doesn't make it right. It's nice that the libc's printf does all
these neat tricks, but it's also expensive (See the link I posted
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
type. This is C after all.
> -----
> $ cat 1.c
> #include <stdio.h>
>
> int main(void)
> {
> void *ptr = 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.
--
/"\ Best regards, | mlaier@freebsd.org
\ / Max Laier | ICQ #67774661
X http://pf4freebsd.love2party.net/ | mlaier@EFnet
/ \ ASCII Ribbon Campaign | Against HTML Mail and News
[-- Attachment #2 --]
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (FreeBSD)
iD8DBQBF9qQBXyyEoT62BG0RAqONAJwOCMP+nq0RW+AzM/dr2dvZltMc0wCbBIpF
eqzpU0iXc9xBu6h9qPJyuT8=
=vBHA
-----END PGP SIGNATURE-----
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200703131415.45709.max>
