I wrote a complex program for the Arduino Uno. It uses an I2C 4x20 LCD. It generates a random number to extract a character from a string and send it in Morse code. At this point I wanted to output data on how many of each character is sent so I can evaluate just how random the characters are. It worked fine up to a certain point. Then any attempt to output data to the serial monitor caused the program to hard reset. The first Serial.println would work OK. The second caused a hard reset. After hours of trial and error I can find no solution. It worked and then suddenly began this behavior.
At various points I had compiler errors which were segment faults of some kind. I have no idea where to send such errors.
int counts[42];
...
for(int i = 0; i < sizeof(counts); i++)
{
counts[i] = 0;
}
The type of counts is int. On the Uno, an int is 2 bytes. That means that sizeof(counts) == 84. Writing past the bounds of an array will result in undefined behavior which may include resets.
The correct way to determine the number of elements in an array is:
for(int i = 0; i < (sizeof(counts) / sizeof(counts[0]); i++)
That will work with any type
dxvictor:
At various points I had compiler errors which were segment faults of some kind. I have no idea where to send such errors.
This bug is specific to the 5.4.0-atmel3.6.1-arduino2 version of avr-gcc used by Arduino AVR Boards 1.6.22 and newer. It has been reported here:
Here's the traditional workaround:
Tools > Board > Boards Manager
Wait for downloads to finish.
When you move the mouse pointer over "Arduino AVR Boards", you will see a "Select version" dropdown menu appear. Select "1.6.21".
Click "Install".
Wait for installation to finish.
Click "Close".
Due to a bug, this workaround doesn't work with Arduino IDE 1.8.6, but it will work with any other version of the Arduino IDE.
If you have File > Preferences > Check for updates on startup checked, the Arduino IDE may occasionally notify you that a new version of Arduino AVR Boards is available, you'll need to refrain from updating back to the new Arduino AVR Boards version, otherwise you'll be back to seeing the segmentation fault error again.
Alternate workaround:
One of the Arduino developers recently worked on this and claims to have fixed it. There is a special beta testing hardware package you can install via the Arduino IDE's Boards Manager that has the fix:
(In the Arduino IDE) File > Preferences
In the "Additional Boards Manager URLs" field, enter: http://downloads.arduino.cc/packages/package_avr_7.3.0_index.json If you already have an additional Boards Manager URL in that field, you can separate multiple URLs with commas or click the button on the right side of the field to open a dialog that allows you to add each on its own line.
I have a complex program designed to provide training in copying Morse code. Everything was working fine until suddenly the program seemed to be in a loop resulting in a hard reset - by which I mean the program restarted from setup(). I output data to the serial monitor as I go thru various steps. The reset occurred at the second instance of Serial.println(). Nothing important has happened so far. I can find nothing that suggests why this is happening. I have tried 1.88, 1.87, 1.90. 20 hours of work and a couple hundred lines of code and serial.println is stopping me in my tracks. Remove all Serial calls results in the program working correctly. I have no idea what to do.
Use of String variables was not the problem. It appears that the problem was my lack of understanding on how to determine the correct size of an array. Once sizeof() was removed, the program began working normally. How this caused Serial.print() to fail before this call was encountered is a mystery to me.
Two things that can cause that behaviour are using the String class (causes memory fragmentation if not used carefully) or writing to memory that you do not "own" by writing past the end of an array, so those are my guesses in the absence of code to examine.
Writing to memory you don't own causes "undefined behavior". Usually that means "crash" but you can get subtle errors without an immediate crash.
This is how most viruses compromise your computer. Finding some privileged process with this bug and causing it to write a specially-crafted payload which gives the virus that same privilege. Otherwise known as an "exploit."
Fortunately viruses are rarely a problem on an Arduino because you're not connected to the wild internet and there's no way for an attacker on the "inside" of your Arduino to find out that digitalWrite(2) controls your fish feeder.