Author Topic: Weird bug in GCC ARM 32F4  (Read 2294 times)

0 Members and 1 Guest are viewing this topic.

Offline peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 3697
  • Country: gb
  • Doing electronics since the 1960s...
Weird bug in GCC ARM 32F4
« on: December 01, 2021, 10:00:16 pm »
The code crashes in the sprintf, into one of the illegal instruction traps. However I found that shortly before it, data which is supposed to be initialised on the stack, isn't. AIUI, if you do say int x=2; inside a function, the compiler generates some code which sets up that data, and it puts it on the stack (unless it is declared "static" in which case it goes into, IIRC, BSS).

Here the bytes remain 0xFF. Does this make any sense to anybody?

The code runs fine when loaded with the STLINK debugger, and has done so for ages. It crashes when loaded from a serial FLASH device, into the CPU FLASH. Then the system reboots (as is necessary) and promptly crashes. Could this data be stored at the very end of the file, and I am failing to load the entire image?

Where in the binary would the string MonTue... be stored - for stuff destined for the stack? I guess it is missing. The 0xFF bytes are indicative of an erased FLASH device. SP and PC look good; the stack is at the top of the 128k RAM.

« Last Edit: December 01, 2021, 10:03:44 pm by peter-h »
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Online langwadt

  • Super Contributor
  • ***
  • Posts: 4425
  • Country: dk
Re: Weird bug in GCC ARM 32F4
« Reply #1 on: December 01, 2021, 10:10:07 pm »
look at the disassembly
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11258
  • Country: us
    • Personal site
Re: Weird bug in GCC ARM 32F4
« Reply #2 on: December 01, 2021, 10:31:22 pm »
How exactly do you obtain the file that you put into the flash?

This constant string will typically go into .rodata section. Where it is located depends on your linker script. With more or less standard linker scripts, all those strings will be located at the end of the binary, after all the code (text) sections.

Indeed, look at the disassembly and see what is actually going on.

Also, it is not a bug in GCC. It is a bug somewhere in your system. Compiler bugs are much more rare than you think, and chances of you running into one are negligible.
« Last Edit: December 01, 2021, 10:38:52 pm by ataradov »
Alex
 

Offline peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 3697
  • Country: gb
  • Doing electronics since the 1960s...
Re: Weird bug in GCC ARM 32F4
« Reply #3 on: December 01, 2021, 10:51:14 pm »
Sorry; didn't mean to say it is a bug in GCC :)

It is a system built with GCC ARM 32F4 :)

The file comes from a FAT file system, originally, implemented on the target via USB. But that aspect of the project has been working for 1+ year, until a few weeks ago. Recently it has grown in size (by replacing PolarSSL with MbedTLS) from 170k to 300k and this issue has appeared. My code should support a file up to 510k (size of the entire binary) so that's not the simple answer, but I can see I may be dropping something off the end..

Disassembly:



I can see the two arrays are initialised to zero with explicit instructions (r5=0 etc). But I can't see how the MonTue... bit gets initialised.

In the linkfile, it does indeed look like rodata is loaded after all the code

Code: [Select]
.main.o :
  {
    . = ALIGN(4);
    KEEP(*(.main.o))
    *main.o (.text .text* .rodata .rodata*)
    . = ALIGN(4);
  } >FLASH_APP
 
/* This collects all other stuff, which gets loaded into FLASH after main.o above */
 
  .text :
  {
    . = ALIGN(4);
    *(.text)           /* .text sections (code) */
    *(.text*)          /* .text* sections (code) */
    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
    *(.glue_7)         /* glue arm to thumb code */
    *(.glue_7t)        /* glue thumb to arm code */
*(.eh_frame)

    KEEP (*(.init))
    KEEP (*(.fini))

    . = ALIGN(4);
    _etext = .;        /* define a global symbol at end of code */
} >FLASH_APP

Thank you for any pointers, so to speak.
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11258
  • Country: us
    • Personal site
Re: Weird bug in GCC ARM 32F4
« Reply #4 on: December 01, 2021, 11:10:02 pm »
ldmia and stmia instructions starting from 0x803abc6 is what loads that constant string to the stack.

So you can look at the address stored in r6 before the first instructions is executed. As you can see that address is located in a constant pool at the end of the function and is loaded by the ldr instruction (from address 0x803ac60). Your binary should contain that string at that address.
Alex
 

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14471
  • Country: fr
Re: Weird bug in GCC ARM 32F4
« Reply #5 on: December 01, 2021, 11:13:22 pm »
Note that the following declaration for 'dow' would have made more sense here:

const char *dow = "MonTue...";

No need to allocate an array on the stack to have it initialized with a string constant at run-time, here. You're wasting stack space and CPU cycles.

And, have you checked the value of sDate.WeekDay?
 
The following users thanked this post: thm_w

Offline peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 3697
  • Country: gb
  • Doing electronics since the 1960s...
Re: Weird bug in GCC ARM 32F4
« Reply #6 on: December 02, 2021, 08:23:18 am »
Thanks everyone. Yeah, I can see 0x803ac60 contains 0x8055398 which contains... FFs. In fact everything above 0x8048000 is FFs.

The .map file shows that rodata starts shortly above that value, so I am losing all of that. I am dropping 57632 bytes off the end of the file! Is there anything in the 32F417 which happens at 0x8048000? It doesn't lie on one of the FLASH block boundaries.

The binary file is fine; the code runs via a debugger ok.

Thanks for the coding tips. It was actually written by someone else :) I would have declared it as static. I made the mistake once of declaring an array of about 1k bytes inside a function and then found the function was running really slowly :) Yes; that index should be checked.
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11258
  • Country: us
    • Personal site
Re: Weird bug in GCC ARM 32F4
« Reply #7 on: December 02, 2021, 08:32:06 am »
Just debug the writing procedure and see the error code it returns. There is no point in guessing. It may not even be a write issue, but SD Card reading issue, or FS issue.
Alex
 

Offline peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 3697
  • Country: gb
  • Doing electronics since the 1960s...
Re: Weird bug in GCC ARM 32F4
« Reply #8 on: December 02, 2021, 09:51:29 am »
Spot the mistake :)

Code: [Select]
for (uint32_t block32k=1; block32k<16; block32k++) // 1-15
  {

  // Read each 32k block into buffer1
  buffer1idx=0;
  for ( uint32_t page=pagebase; page<(pagebase+64); page++ )
  {
  AT45dbxx_ReadPage(&buffer1[buffer1idx],512,page*512);
  buffer1idx+=512;
  }

  // Program 32k block
  L_HAL_FLASH_Unlock();
  for (uint32_t i=0; i<(32*1024); i+=4)
  {
  uint32_t data=buffer1[i]|(buffer1[i+1]<<8)|(buffer1[i+2]<<16)|(buffer1[i+3]<<24);
  L_FLASH_Program_Word(i+cpubase, data);
  }
  L_HAL_FLASH_Lock();

  // Verify 32k block against buffer1
  for (uint32_t i=0; i<(32*1024); i+=4)
  {
  uint32_t data=buffer1[i]|(buffer1[i+1]<<8)|(buffer1[i+2]<<16)|(buffer1[i+3]<<24);
  if ( (*(volatile uint32_t*) (i+cpubase)) != data ) error++;

}

  cpubase+=(32*1024);
  pagebase+=64;
  block32k++;

  }

Two lots of fossil code there. One is the block32k++. The other is the fact that black32k is not used within the loop. That is why everything worked for binary files up to 8 blocks (256k) or so.
« Last Edit: December 02, 2021, 10:21:18 am by peter-h »
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf