Re: Bad gcc -O optimization cause core dump. What to do?

From: Hartmut Brandt <Hartmut.Brandt_at_dlr.de>
Date: Tue, 13 Mar 2007 14:04:41 +0100
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:
> -----
> $ cat 1.c
> #include <stdio.h>
>
> int main(void)
> {
>         void    *ptr = NULL;
>         func(ptr);
> }
>
> int func(void *ptr)
> {
>         printf("%s\n", ptr);
> }
> :: rea_at_codelabs : 15:31:43 : ~/xlam
> $ cat 1.s
>         .file   "1.c"
>         .text
>         .p2align 2,,3
> .globl main
>         .type   main, _at_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, _at_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.
>   
The behaviour of gcc is correct. Passing NULL to the %s of printf() 
produces undefined behaviour. The compiler is free to do what ever it 
wants including burning your house. Depending on printf to print (null) 
or whatever is just bad programming.

harti
Received on Thu Mar 15 2007 - 18:42:32 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:06 UTC