Yahoo Groups archive

AVR-Chat

Index last updated: 2026-04-28 22:41 UTC

Thread

Re: Understanding, trapping and debugging stack overflow on an AVR

Re: Understanding, trapping and debugging stack overflow on an AVR

2011-01-11 by Don Kinzer

--- In AVR-Chat@yahoogroups.com, "Chuck Hackett" <egroupscdh@...> wrote:
>[...] but very shortly after that it re-executes the "main"
>function (as shown by a breakpoint).
That sounds like it could be data corruption due to the stack colliding with statically allocated data.  It could, however, be an interrupt for which you have defined no handler.

> I think I need to understand WinAVR frames better
> to track this down - besides, I should know it anyway ...
The avr-libc documentation (installed with WinAVR in the 'doc' directory) contains a brief description of how parameters are passed to functions.  When possible, the parameters are all passed in registers so the stack frame consists only of the return address.  If you have too many parameters to be passed in registers only, some of them are pushed on the stack.  The stack is also used for calling variadic functions.

If a function allocates local storage that is too large to be held in registers, space is created on the stack for the extra variables.  These variables are references by an offset from the Y register.  Since r29:28 are among the "call preserved" registers, the previous content of r29:28 are pushed on the stack, too.

You can best understand how all of this works by looking at the .lss file to see what code is generated in different circumstances.  Some simple test cases will allow you to create different scenarios.

> Other than that, and suggestions on tracking this
> down would be welcome.
It is often useful to capture the "reset flags" (typically in the MCUCR register but check your datasheet) and then clear them.  This register has bits for each reset cause.  If you get back to main() and no reset flags are set then you know that you got there by a means other than a reset.

You can set a breakpoint on the "catch all" ISR to detect when that is the cause of restarting.

You can "seed" the stack area with a known value and then inspect it at various times to detect when the stack is all "used up".  This will be more complicated in a multi-tasking environment because you undoubtedly have multiple stacks.

Don Kinzer
ZBasic Microcontrollers
http://www.zbasic.net

Understanding, trapping and debugging stack overflow on an AVR

2011-01-11 by Chuck Hackett

I'm fairly sure that I'm into a stack overflow/buffer overrun bug in my (FreeRTOS
based) application on an ATMega32A.

It gets through initialization and initial task creation but very shortly after that
it re-executes the "main" function (as shown by a breakpoint).  My guess is that
this is most likely due to executing a 'return' through a clobbered stack
frame/marker.

I think I need to understand WinAVR frames better to track this down - besides, I
should know it anyway ...

Can someone suggest a good web site/doc where I can read about the stack
frames/markers produced by WinAVR (GCC)?

At the moment, I'm trying to 'sneak up on it' with breakpoints, UART traces,
disabling sections of code, disabling interrupt handlers, etc.  FreeRTOS has some
stack overflow detection logic (which I have turned on) but, AFAIK, it is only
invoked on task switches.

Another question:  Is there a way to have WinAVR emit a macro/function invocation on
function entry and exit?  This would help 'instrument' the code with verification
logic.  I know I can insert my own but I wondered if there was a WinAVR supported
way to do this quickly and thoroughly.

A "stack trace back" would be nice but it's not available in AVRStudio.  I have not
yet gotten up the GDB (which I believe does have a stack trace back) interface in
the Code::Blocks IDE yet (maybe my time would be well spent on that ...).

Other than that, and suggestions on tracking this down would be welcome.

General Pondering:  Stack overflow can be a difficult problem because, particularly
in embedded systems, it is dependent on the 'worst case' stack depth which is
subject to interrupt timing, etc.  I wonder why processor manufacturers have not
added a hardware "Stack Fence", such that, if the stack grows past this a trap
occurs.  Sure would be nice for me at the moment and, I suspect, would catch some
product malfunctions in the field.
 
Cheers,

Chuck Hackett
"Good judgment comes from experience, experience comes from bad judgment"
7.5" gauge Union Pacific Northern (4-8-4) 844 http://www.whitetrout.net/Chuck

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.