Variables Losing Their Assigned Values

Status
Not open for further replies.

RFModulator

Member
I've had a few weird things happen to me with this project I've been working on for the past few months. I'm using a Teensy 3.6 and my code spans across several files, and I use my own Makefile to put it all together. I feel it's impossible to give specific examples since there's too much code for someone to look at (~4000 lines) and it's not feasible to post a snippet that would exemplify the problem. Regardless, I'm hoping someone (who probably knows more than me) could please tell me what they would be suspicious of if they were to see the following behavior:

On three separate occasions, I've had external boolean variables (defined as bool) somehow end up holding the wrong value; that is to say, for example, that when I set a variable to be false and then look at its value later on in the code, I'm seeing a number >0. Each time, I've assured myself that no section of my code that can reassign the boolean's value was being called. I've "solved" each of these occurrences by moving the declaration of the extern variable into a different file. It's hard for me to understand why that would "solve" the problem, and it seems quite odd that this would happen "out of nowhere" when I was not working on any part of the code that had anything to do with the assignment of these variables. Regardless, the problem went from occurring 100% of the time (out of nowhere) to never happening again after I made the modification.

The other thing that just happened to me is that I set a variable to be NULL at the beginning of the program, and when I go to read its value, somehow it is no longer NULL even though I'm certain no part of my code is accessing it or reassigning a different value to it. This part of the program has been working for months. It's not clear at what part of the execution the variable is "losing" its value, and it would be pretty hard to track that down. Again, I wasn't working on any part of the code that had anything to do with this variable when it seemingly started behaving this way.

So, does anybody have any guesses as to what might be going on here? It has me pretty concerned that there might be a big issue afoot, and I wonder if my compiler or linker flags are to blame. I just copied what the Arduino IDE was using to compile Blink.

My cpp files are compiled with:
Code:
-c -O2 -g -Wall -ffunction-sections -fdata-sections -nostdlib -MMD -fno-exceptions -felide-constructors -std=gnu++14 -fno-rtti -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -fsingle-precision-constant -D__MK66FX1M0__ -DTEENSYDUINO=140 -DARDUINO=10805 -DF_CPU=48000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH
My c files are compiled with:
Code:
-c -O2 -g -Wall -ffunction-sections -fdata-sections -nostdlib -MMD  -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -fsingle-precision-constant -D__MK66FX1M0__ -DTEENSYDUINO=140 -DARDUINO=10805 -DF_CPU=48000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH
And my linker options are:
Code:
-O2 -Wl,--gc-sections,--relax,--defsym=__rtc_localtime=$(shell date +%s) -lstdc++ -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -fsingle-precision-constant -larm_cortexM4lf_math -lm -T"$(LDPATH)/$(MCU_LD)"
 
if you have variables updating in an ISR they should be declared volatile, perhaps the code is too big (4k lines) but perhaps you should post maybe what libraries your using, we might be able to help better
 
I should have mentioned that I have no ISRs in my code, although some of the libraries I employ might have their own.

I'm using the following libraries:

EEPROM, SD, SPI (used by SD), Time, LiquidCrystal, Bounce, Snooze, and LinkedList

I don't think I'm brushing up against any limits here:
Code:
"C:\Program Files (x86)\Arduino\hardware\tools\arm\bin/arm-none-eabi-size" flush_control.elf
   text    data     bss     dec     hex filename
  80984    3200    5861   90045   15fbd flush_control.elf
 
Re: the heisenbug
Often such bizarre behavior results from buffer overflows -- array indexing out of bounds or bad pointer variables (C strings/char * stuff like memcpy, sprintf, strcpy). Check Snooze usage and LinkedList usage. Validate constructs like data=val; or file.read(buff,n); Perhaps stack-heap collision?

bug.gif
 
Last edited:
The Heisenbug....that's great! I just wish it wasn't showing up again so close to a deadline!

Anyway, this problem first showed up around the time I added a bunch of strcpy commands. I have some guesses as to where to start my search. I'll report back with the results (if any). Thanks everyone!
 
Yup, strcpy is one of the common ways to get a buffer overflow. Usually the approach most people end up taking involves just replacing all strcpy with something like strcpy_safe() or strncpy() or snprint(). But if you use strncpy(), be careful about how it doesn't null terminate in all cases.
 
Re: the heisenbug
Often such bizarre behavior results from buffer overflows -- array indexing out of bounds or bad pointer variables (C strings/char * stuff like memcpy, sprintf, strcpy). Check Snooze usage and LinkedList usage. Validate constructs like data=val; or file.read(buff,n); Perhaps stack-heap collision?

View attachment 12804


@Manitou - your post seems to have a very active bug in it :confused:
 
I wasn't familiar with strcpy_safe(). That looks great, thanks for mentioning it, Paul! I'll report back once I've had time to track this down.

I'm very curious as to why the compiler and linker options vary between the example Makefile and what the Arduino IDE uses. Generally speaking, is one set of rules preferable over the other?

For C/C++ files, the example Makefile uses Os instead of O2 in the Arduino IDE, and these options are used in addition to what's in the sample Makefile:
Code:
-c -g -ffunction-sections -fdata-sections -nostdlib -MMD -mfloat-abi=hard -mfpu=fpv4-sp-d16 -fsingle-precision-constant

For C++ files, these options are used in addition to what's in the sample Makefile:
Code:
-c -O2 -g -Wall -ffunction-sections -fdata-sections -nostdlib -MMD -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -fsingle-precision-constant

And for the Linker, these options are used in addition to what's in the sample Makefile:
Code:
-O2 --relax, -lstdc++ -mfloat-abi=hard -mfpu=fpv4-sp-d16 -fsingle-precision-constant -larm_cortexM4lf_math -lm
 
teensy supports strlcpy but i think paul forgot to add it to the keyword list, it doesnt turn color when used in IDE :eek:
 
I changed all of my strcpys to strlcpy and all my strcats to strlcat. The problem has disappeared! I don't know if I've just kicked the can down the road, so to speak, or if I actually eliminated all sources of trouble. Maybe as I continue working, I'll figure out which buffer (if any) was too small. Thanks again for the suggestions.

I'm still curious to know the information in my previous post, if anyone has the time to share it.
 
I figured out what was going on. I made some arrays to hold filenames to be read/written on an SD card. I made their length 13, which was appropriate, and used strcpy to move values in and out. However, when I changed my implementation to save the files in specific folders, I never increased the lengths of the filename char arrays to hold the new characters associated with the folder names. So, I had several instances where I was overrunning the buffer by several characters. D'oh!

Lesson learned: using strncpy/strlcpy makes a lot of sense and can avoid headaches later on.
 
Status
Not open for further replies.
Back
Top