Stack overflow

Hi,

How is a stack overflow visible in a project ? Does it reset the Arduino or is there a specific interrupt that gets triggered or do you just find out through unexpected behavior ?

Thanks

Duane B

rcarduino.blogspot.com

do you just find out through unexpected behavior ?

That's the one.

Thanks,

I have just made a few changes that should be good for 30 or 40 bytes, I am running on an 1K ATMega8 and the project is behaving as if a global variable is being overwritten with zero after a period.

Duane.

or is there a specific interrupt that gets triggered

You mean some sort of mechanism that pushes the machine's current state and registers onto the stack? :wink:

You mean some sort of mechanism that pushes the machine's current state and registers onto the stack?

Now that you mention it - :blush:

You might be able to see it occur if you run the hex file in a simulator like AVR Studio 4, I show it happening here:

AWOL:
You mean some sort of mechanism that pushes the machine's current state and registers onto the stack? :wink:

Very amusing. :slight_smile:

The stack that is no more?

Some more advanced microcontrollers do have a system for handling this. It's just like an interrupt, but it's called an "exception". They are more critical than interrupts, and you aren't always expected to be able to return from it. They are usually linked to such events as "address error", or "divide by 0" and other such critical events.

Not something the low-end Atmel chips do I'm afraid.

My favourite was the 68000 double bus error.
A single bus error caused the processor to jump via a vector when an area of memory that wasn't mapped was accessed.
A double bus error occurred when the bus error vector pointed to a region of memory that wasn't mapped!

DuaneB:
How is a stack overflow visible in a project ?

The Blue Screen Of Death.

Oh, wait. There isn't a screen.

AWOL:
My favourite was the 68000 double bus error.
A single bus error caused the processor to jump via a vector when an area of memory that wasn't mapped was accessed.
A double bus error occurred when the bus error vector pointed to a region of memory that wasn't mapped!

I'm sure my guru meditated on that problem many a time :slight_smile:

Just out of interest - I am not near an AVR now, what does it do for divide by zero ?

Duane B

Divide by zero?
Nothing at all.
Carries on, regardless.

DuaneB:
Just out of interest - I am not near an AVR now, what does it do for divide by zero ?

void setup() {
	Serial.begin(9600);
	unsigned int numerator = 47;
	unsigned int denominator = 0;
	unsigned int result = numerator / denominator;

	Serial.print("Int: ");
	Serial.println(result);
	float floatNumerator = 47.0;
	float floatDenominator = 0.0;
	float floatResult = floatNumerator / floatDenominator;
	Serial.print("Float: ");
	Serial.println(floatResult);
}

Resulted in:

Int: 65535
Float: 0.00

Divide by zero is a concept that we have, to the computer it is just another operation. Sometimes we build the "this is a bad thing" concept into the processor, other times into the software, but the processor dosn't cair.

Thanks for doing the test, and the answer is not nothing !

Very interesting that the two data type return different logical results -

int - cant do it but if you were close to zero it would be big a big number so here you go
float - cant do it, not going to try so instead of float_max,inf or something else I am going to give you a 0 ?

The int handling would seem the most appropriate, but then you could argue that you should account for and uncover the float handling in testing - what doesnt make much sense to me is to implement both approaches in a single device.

Duane B

int - cant do it but if you were close to zero it would be big a big number so here you go

The example used "unsigned int", so you might expect a divide by zero on an "int" type to return 32767, but of course, it returns -1.

Dividing by zero is not defined. By definition, not defined has an undefined result.

In ordinary (real number) arithmetic, the expression has no meaning, as there is no number which, multiplied by 0, gives a (a?0), and so division by zero is undefined.

Just to amplify, once the result is not defined, you may as well be looking at random memory. It could be "correct" to return 0, 65535, -1, or a different number every time. So the library is not wrong to return one number, nor another number. Nor is the library constrained to return what another library returns.

I might have expected it to return NaN but apparently not. For example in this code:

volatile float a, b, c;

void setup () 
{
Serial.begin (115200);
Serial.println ();
c = 0.0;

a = 1.0;

a /= c;

Serial.println (a);
Serial.println (isnan (a));
}

void loop () {}

That prints:

0.00
0

However, sqrt (-1) returns true for isnan.