Re: Crash when cross compiling for ARM with GCC-8-2-0 and -ftree-loop-distribute-patterns

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 10/17/19 1:31 PM, Josef Wolf wrote:
> Thanks for your Help, Martin!
> 
> On Wed, Oct 16, 2019 at 12:18:15PM -0600, Martin Sebor wrote:
>> On 10/16/19 7:17 AM, Josef Wolf wrote:
>>> Hello all,
>>>
>>> I experience target crashing when cross compiling for ARM with
>>> -ftree-loop-distribute-patterns, which is enabled by the -O3 flag.
>>>
>>> The crash happens in the startup code, before main() is called. This startup
>>> code looks like this:
>>>
>>>  extern unsigned long _sidata; /* Set by the linker */
>>>  extern unsigned long _sdata;  /* Set by the linker */
>>>  extern unsigned long _sbss; /* Set by the linker */
>>>  extern unsigned long _ebss;  /* Set by the linker */
>>>   void Reet_Handler (void)
>>>   {
>>>     unsigned long *src = &_sidata
>>>     unsigned long *src = &_sdata
>>>     /* Copy data segment into RAM */
>>>     if (src != dst) {
>>>       while (dst < &_edata)
>>>         *(dst++) = *(src++);
>>>     }
>>>     /* Zero BSS segment */
>>>     dst = &_sbss;
>>>     while (dst < &_ebss)
>>>       *(dst++) = 0;
>>>     main();
>>>   }
>>>
>>>
>>> With -ftree-loop-distribute-patterns those two loops are replaced by calls to
>>> memcpy() and memset().
>>>
>>> The memcpy function finishes just fine. But the memset function doesn't seem
>>> to finish.  It looks like this:
>>>
>>>   void memset (void *s, int c, size_t n)
>>>   {
>>>     int i;
>>>     for (i=0; i<n; i++)
>>>       ((char *)s)[i] = c;
>>>   }
>>
>> This is probably not the cause of the crash but it's worth keeping
>> in mind.  The standard memset function returns void* and (unless
>> disabled) recent versions of GCC will issue a warning:
> 
> Ooops!
> 
> This was actually my fault. Since the computer doesn't have network, I
> had typed the code by hand into the mail.
> 
> Although I double-checked multiple times, I managed to introduce several
> typos :-///
> 
> Sorry for the confusion!
> 
> 
> The code of Reset_Handler() and memset() actually looks like this:
> 
>     void Reset_Handler (void)
>     {
>       unsigned long *src = &_sidata
>       unsigned long *dst = &_sdata
> 
>       /* Copy data segment into RAM */
>       if (src != dst) {
>         while (dst < &_edata)
>           *(dst++) = *(src++);
>       }
> 
>       /* Zero BSS segment */
>       dst = &_sbss;
>       while (dst < &_ebss)
>         *(dst++) = 0;
>  
>       main();
>     }
> 
>     void *memset (void *s, int c, size_t n)
>     {
>          int i;
>          for (i=0; i<n; i++)
> /* B */   ((char *)s)[i] = c;
>    
> /* B */ return s;
>     }
> 
>>> Any ideas why this function is crashing? I can't see anything suspicious here.
>>
>> I doubt it's the cause of the crash either but only addresses of
>> bytes of the same object can be used in relational expressions
>> (i.e., the two less-than controlling expressions).
> 
> Hmm, you are talking about the two loops in Reset_Handler(), right?
> 
>> Using address to unrelated objects is undefined.
> 
> Hmmm... I am not an expert on this topic. But I tend to think the BSS segment
> is an object, which in turn is an array of uint8_t and/or uint32_t.
> Taking the address one past the last element of an array for comparison is
> a perfectly valid operation, AFAIK.
> 
> So what would be the proper way to communicate the dimensions of the BSS
> segment from the linker to the runtime of the compiled program?
> 
> The memset() function is called with the right parameters. And it seems to
> work when I single-step it on instruction level (that is, "stepi" command in
> gdb). But it crashes if I set breakpints to the two instructions marked above
> and use the "cont" statement or the "step" statement in gdb.
> 

Have a look at "arm-eabi-objdump -S -d main.elf". Sometimes this is
quite revealing.

Are you using openocd or something similar for debugging? You are
compiling for a cortex-m0/3/4? Are you single stepping through the
complete startup sequence or do set a break point ath the top of memset
(i.e. are break points working at all)?

Interrupts are still disabled?

Why is the stack pointer so low at this point of execution? Using
0x20018000-0x20017d20 == 0x2e0 bytes of stack seems a little excessive
for just one call.

I usually start toggling output lines when I'm stuck like this...

Matthias
-- 
Matthias Pfaller                          Software Entwicklung
marco Systemanalyse und Entwicklung GmbH  Tel   +49 8131 5161 41
Hans-Böckler-Str. 2, D 85221 Dachau       Fax   +49 8131 5161 66
http://www.marco.de/                      Email leo@xxxxxxxx
Geschäftsführer Martin Reuter             HRB 171775 Amtsgericht München

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature


[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux