Obscure crashes due to gcc 4.9 -O2 => -fisolate-erroneous-paths-dereference

Joel Sherrill joel.sherrill@oarcorp.com
Thu Feb 19 21:23:00 GMT 2015

On 2/19/2015 2:56 PM, Sandra Loosemore wrote:
> Jakub Jelinek wrote:
>> On Wed, Feb 18, 2015 at 11:21:56AM -0800, Jeff Prothero wrote:
>>> Starting with gcc 4.9, -O2 implicitly invokes
>>>     -fisolate-erroneous-paths-dereference:
>>> which
>>>     https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
>>> documents as
>>>     Detect paths that trigger erroneous or undefined behavior due to
>>>     dereferencing a null pointer. Isolate those paths from the main control
>>>     flow and turn the statement with erroneous or undefined behavior into a
>>>     trap. This flag is enabled by default at -O2 and higher.
>>> This results in a sizable number of previously working embedded programs mysteriously
>>> crashing when recompiled under gcc 4.9.  The problem is that embedded
>>> programs will often have ram starting at address zero (think hardware-defined
>>> interrupt vectors, say) which gets initialized by code which the
>>> -fisolate-erroneous-paths-deference logic can recognize as reading and/or
>>> writing address zero.
>> If you have some pages mapped at address 0, you really should compile your
>> code with -fno-delete-null-pointer-checks, otherwise you can run into tons
>> of other issues.
> Hmmmm,  Passing the additional option in user code would be one thing, 
> but what about library code?  E.g., using memcpy (either explicitly or 
> implicitly for a structure copy)?
> It looks to me like cr16 and avr are currently the only architectures 
> that disable flag_delete_null_pointer_checks entirely, but I am sure 
> that this issue affects other embedded targets besides nios2, too.  E.g. 
> scanning Mentor's ARM board support library, I see a whole pile of 
> devices that have memory mapped at address zero (TI Stellaris/Tiva, 
> Energy Micro EFM32Gxxx,  Atmel AT91SAMxxx, ....).  Plus our simulator 
> BSPs assume a flat address space starting at address 0.
I forwarded this to the RTEMS list and was promptly pointed to a patch
on a Coldfire BSP where someone worked around this behavior.

We are discussing how to deal with this. It is likely OK in user code but
horrible in BSP and driver code. We don't have a solution ourselves. We
just recognize it impacts a number of targets.

> I can see both sides of the issue here....  On the one hand, you get 
> better code for 99.99% of situations by enabling 
> -fdelete-null-pointer-checks, but if it makes GCC unusable in the other 
> .01% case, that is a problem for the users for whom that case is 
> critical.  :-S  So I think  Jeff's request here is something that 
> deserves an answer:
Which side is benefiting? The embedded side or self-hosted side?
What is the actual benefit?

Can the option be disabled/enabled on a per target basis?  I honestly
could see disabling it for *-rtems* and on purely embedded
>>> BTW, I'd also be curious to know what is regarded as engineering best
>>> practice for writing a value to address zero when this is architecturally
>>> required by the hardware platform at hand.  Obviously one can do various
>>> things to obscure the process sufficiently that the current gcc implementation
>>> won't detect it and complain, but as gcc gets smarter about optimization
>>> those are at risk of failing in a future release.  It would be nice to have
>>> a guaranteed-to-work future-proof idiom for doing this. Do we have one, short
>>> of retreating to assembly code?
Or GCC specific code.

I considered a special memcpy clone for our BSPs which was not inlined
and used a pragma to turn this optimization off. Then it would just
be a matter of using it in the right places. But knowing all the right
is a hard problem by itself. :(
> -Sandra

Joel Sherrill, Ph.D.             Director of Research & Development
joel.sherrill@OARcorp.com        On-Line Applications Research
Ask me about RTEMS: a free RTOS  Huntsville AL 35805
Support Available                (256) 722-9985

More information about the Gcc mailing list