Corrupted uint16 variable in a 4000 line main_cm0p.c file

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
TeMa_1467596
Level 5
Level 5
5 sign-ins 5 likes given First like received

I have a 4050 line main_cm0p.c file in PSoC Creator using GCC 5.4-2016-q2-update compiler.  It's been working fine but I now have a uint16 variable that is a counter that's only used within main_cm0p.c to keep track of the next free memory slot (there are 1000 slots in my system).  The variable is defined...

uint16 nextFreeFFslotNumber = 0;

at the top of my file and then it's set in a function called by main and I've printed the value out over UART after it's set and it is fine.  At some point when an event happens, I use it to generate a load of addresses and then I increment it like this...

dirRecord.slotRef = nextFreeFFslotNumber++;

but the value that was ending up in slotRef is wildly wrong, like 2570 (always the same number) when it should be 3 or 4.  I've tried printing nextFreeFFslotNumber at several places and found out that it gets corrupted before it even gets to the line of code above (that line does increment it from 2570 to 2571) and there are no other places that the value is set!!!!

I tried making the declaration volatile (and static) but the problem is the same.  I tried taking out the optimization and changing the optimization level for the cm0 but it's still broken.  Now I'm thinking that there's another variable that's corrupting this one.  Any ideas or suggestions how to debug this?  How do I get to look at the .map file to see what's before it?

0 Likes
1 Solution
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

This sounds like there is a memory overrun access by neighbor variable(s).

Don't you have some array defined near the variable nextFreeFFslotNumber ?

Something like

=====

   char strArray[6] ;

   uint16 nextFreeFFslotNumber = 0

   int intArray[8] ;

=====

Then accessing strArray[6] or strArray[7] by such as

    sprintf(strArray, "%s", "a sting which is more than 5 letter long") ;

or

   for (i = 0 i < 10 ; i++ ) { /* index 8 and 9 are overrun access */

      intArray[8] = i * 32 ;

  }

Off my head, I'm not sure which (after or previously defined) variable is the problem,

but accessing an array with exceeding its defined capacity often causes a symptom like what you wrote.

So it's worth checking.

moto

View solution in original post

7 Replies
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

This sounds like there is a memory overrun access by neighbor variable(s).

Don't you have some array defined near the variable nextFreeFFslotNumber ?

Something like

=====

   char strArray[6] ;

   uint16 nextFreeFFslotNumber = 0

   int intArray[8] ;

=====

Then accessing strArray[6] or strArray[7] by such as

    sprintf(strArray, "%s", "a sting which is more than 5 letter long") ;

or

   for (i = 0 i < 10 ; i++ ) { /* index 8 and 9 are overrun access */

      intArray[8] = i * 32 ;

  }

Off my head, I'm not sure which (after or previously defined) variable is the problem,

but accessing an array with exceeding its defined capacity often causes a symptom like what you wrote.

So it's worth checking.

moto

Motoo San,

Thanks for the suggestion - I had been looking for an array bounds overrun as the likely culprit and today I found exactly that. Then I came here to update my post and found your suggestion but thanks anyway for the input - in fact you were right so I'll give you the correct answer award!

This has caught me out before so here's a question...  isn't there some way to make C tell you when you've addressed an array index outside the defined size?

MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Dear TeMa-san,

Thank you very much for the correct answer mark!

As far as I know of, I have not heard of C language support of Array Boundary checking.

But if you run MISRA-C checking it will warn about possible array over run.

IAR EWARM compiler has such feature, but I'm afraid that general GCC does not.

Best Regards,

11-Nov-2019

Motoo Tanaka

0 Likes

Hi,

You can add a data WatchPoint while debugging, so the code is stopped whenever your variable is written. Depending on optimisations code might stop few instructions away, but it should give you a hint where the error comes from.

pastedImage_0.png

In case a known value is written to the variable, you could check for that value only by using following code:

CoreDebug->DEMCR = CoreDebug_DEMCR_TRCENA_Msk  | /*enable tracing*/

CoreDebug_DEMCR_MON_EN_Msk; /*enable debug interrupt*/

DWT->COMP0 = (int)&test_var; /* set pointer to test Variable */

DWT->MASK0 = 0; /* N/A */

DWT->FUNCTION0 = 0; /* N/A */

DWT->COMP1 = 9;     /* Value to test for */

DWT->MASK1 = 0;     /* match all comparator bits, don't ignore any */

DWT->FUNCTION1 =    (0b00 << 10) |  /* DATAVSIZE 00 - match byte */

(1 << 12) |     /* Data Match compare value pointer in COMP1 */

(1 << 😎 |      /* DATAVMATCH Enable data comparation */

  (0b0110 << 0);  /* generate a watchpoint event on write */

Kind regards,

Achim

Achim,

That sounds useful.  Would it still interrupt if the write to the variable was caused by an out of bounds array?  Is it actually detecting a write to an address rather than a named variable?

Ted

0 Likes

Yes it it watching an address and any write access and/or read based on your configuration is monitored and triggers the interrupt/breakpoint.

There is also the Mask register where you could watch a certain memory area instead of just a single address.

Only thing I noticed is that if you are debugging it will force a breakpoint rather than causing an interrupt. If you run the program it will trigger the interrupt instead.

It is an ARM core feature, so you should find some information on WatchPointer via google.

I don't know if we have any good KBA on it here at cypress.

Achim

Thanks, I looked it up, it's found under "WatchPoint".

Ted

0 Likes