Skip site navigation (1)Skip section navigation (2)
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>