Size of global variable

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
13 messages Options
Reply | Threaded
Open this post in threaded view
|

Size of global variable

ravim
My apologies if I am asking something irrelevant to this forum. We are using mspgcc and mspdebug for our project. We are facing some issues with what we assume might be stack overflow. The timer interrupts stops working after around 2 hours, however device still receives packets. Also, when we reset the device after timer gets stuck, they never turn back on unless we re-install the code.  We are trying to debug.

I wanted to know if there is any possible way we can know the size of global variables in the binary? This will help us narrow down a few specifics. We know there is something in TinyOs when we make, it let us know size of global variables, we are looking for something similar in mspdebug.

We would really appreciate any help.

Thanks


 
Reply | Threaded
Open this post in threaded view
|

Re: Size of global variable

Daniel Beer-3
On Mon, Jul 29, 2013 at 12:56:31PM -0700, ravim wrote:

> My apologies if I am asking something irrelevant to this forum. We are using
> mspgcc and mspdebug for our project. We are facing some issues with what we
> assume might be stack overflow. The timer interrupts stops working after
> around 2 hours, however device still receives packets. Also, when we reset
> the device after timer gets stuck, they never turn back on unless we
> re-install the code.  We are trying to debug.
>
> I wanted to know if there is any possible way we can know the size of global
> variables in the binary? This will help us narrow down a few specifics. We
> know there is something in TinyOs when we make, it let us know size of
> global variables, we are looking for something similar in mspdebug.
>
> We would really appreciate any help.

Try "size <filename.elf>". Add "data" and "bss" to get the total size of
statically allocated data. You can also use size on the individual
object files if you want to narrow down your search, but remember to use
--common if you need global (non-static) variables to be counted.

Cheers,
Daniel

--
Daniel Beer <[hidden email]>    www.dlbeer.co.nz
IRC: inittab (Freenode)    PGP key: 2048D/160A553B

------------------------------------------------------------------------------
Get your SQL database under version control now!
Version control is standard for application code, but databases havent
caught up. So what steps can you take to put your SQL databases under
version control? Why should you start doing it? Read more to find out.
http://pubads.g.doubleclick.net/gampad/clk?id=49501711&iu=/4140/ostg.clktrk
_______________________________________________
Mspgcc-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/mspgcc-users
Reply | Threaded
Open this post in threaded view
|

Re: Size of global variable

Grant Edwards-6
In reply to this post by ravim
On 2013-07-29, ravim <[hidden email]> wrote:
> My apologies if I am asking something irrelevant to this forum. We are using
> mspgcc and mspdebug for our project. We are facing some issues with what we
> assume might be stack overflow. The timer interrupts stops working after
> around 2 hours, however device still receives packets. Also, when we reset
> the device after timer gets stuck, they never turn back on unless we
> re-install the code.  We are trying to debug.
>
> I wanted to know if there is any possible way we can know the size of
> global variables in the binary?

Not easily, no.

It's pretty easy to find the total size of non-automatic initalized
variables (section .data) and total size of non-automatic
uninitialized variables (.bss) by looking at a linker map file or by
using the "size" or "objdump" commands on the linked ELF file.

You can generate a linker file by passing the "-Map <mapfilename>"
option to the linker.  If you are using the "gcc" binary to do the
linking, then you can tell it to pass an option on to the linker by
using the -Wl option:

gcc -Wl,-Map,foo.map -o foo.elf file1.o file2.o file3.o

However, I'm not aware of a simple way to find the sizes of only the
_global_ variables and not include local variables that have a static
storage class (The .bss and .data sections include both global and
local variables).

> This will help us narrow down a few specifics. We know there is
> something in TinyOs when we make, it let us know size of global
> variables, we are looking for something similar in mspdebug.

Why mspdebug?

--
Grant Edwards               grant.b.edwards        Yow! I want a VEGETARIAN
                                  at               BURRITO to go ... with
                              gmail.com            EXTRA MSG!!


------------------------------------------------------------------------------
Get your SQL database under version control now!
Version control is standard for application code, but databases havent
caught up. So what steps can you take to put your SQL databases under
version control? Why should you start doing it? Read more to find out.
http://pubads.g.doubleclick.net/gampad/clk?id=49501711&iu=/4140/ostg.clktrk
_______________________________________________
Mspgcc-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/mspgcc-users
Reply | Threaded
Open this post in threaded view
|

Re: Size of global variable

ravim
In reply to this post by Daniel Beer-3
Thank you so much Daniel, Really appreciate it. This is definitely going to help.
Reply | Threaded
Open this post in threaded view
|

Re: Size of global variable

ravim
Thanks Grant,

Really appreciate your response.

I will try to do what you have suggested. Issue is we fear that so much is happening in our code too fast (flash write, blacklist check, then communication with different devices etc), we fear we might be corrupting stack somehow with so many global and local variables.

Is there any way through which we can figure out what is actually happening (read the stack etc), why things go smooth for an hour or so. If we change sampling window, timing varies but eventually, it will stop.

Reply | Threaded
Open this post in threaded view
|

Re: Size of global variable

Grant Edwards-6
On 2013-07-29, ravim <[hidden email]> wrote:

> I will try to do what you have suggested. Issue is we fear that so
> much is happening in our code too fast (flash write, blacklist check,
> then communication with different devices etc), we fear we might be
> corrupting stack somehow with so many global and local variables.

That doesn't really make much sense.  It doesn't matter how many
things you do or how fast you do them.

Things that will cause intermitten failure after running for a while:

 * stack overflow (or underflow)

 * dereferencing uninitialized pointers

 * buffer overflow (or underflow)
 
 * race conditions
 
To check for stack overflow, the the easiest thing to do is to
initialize your stack space with a recognizable pattern. You can then
periodically check to see how much of the stack still contains that
initial pattern.  If you can stop program execution when it fails, you
can check the stack space to make sure that some of it still contains
the initialization pattern.

> Is there any way through which we can figure out what is actually
> happening (read the stack etc), why things go smooth for an hour or
> so. If we change sampling window, timing varies but eventually, it
> will stop.

If it's not stack overflow, then my _guess_ is that you probably have
a race condition between forground and interrupt, between two
interrupts (if you allow interrupts to nest), or between two threads
(if you've got a multi-threaded system).

--
Grant Edwards               grant.b.edwards        Yow! Should I do my BOBBIE
                                  at               VINTON medley?
                              gmail.com            


------------------------------------------------------------------------------
Get your SQL database under version control now!
Version control is standard for application code, but databases havent
caught up. So what steps can you take to put your SQL databases under
version control? Why should you start doing it? Read more to find out.
http://pubads.g.doubleclick.net/gampad/clk?id=49501711&iu=/4140/ostg.clktrk
_______________________________________________
Mspgcc-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/mspgcc-users
Reply | Threaded
Open this post in threaded view
|

Re: Size of global variable

Daniel Beer-3
In reply to this post by ravim
On Mon, Jul 29, 2013 at 01:47:14PM -0700, ravim wrote:

> Really appreciate your response.
>
> I will try to do what you have suggested. Issue is we fear that so much is
> happening in our code too fast (flash write, blacklist check, then
> communication with different devices etc), we fear we might be corrupting
> stack somehow with so many global and local variables.
>
> Is there any way through which we can figure out what is actually happening
> (read the stack etc), why things go smooth for an hour or so. If we change
> sampling window, timing varies but eventually, it will stop.

If you suspect that you're overflowing the stack, you might want to try
writing a block of test data at the end of the data section. If the
stack gets too large, this data will get overwritten first. Periodically
check it to see if the contents have changed. If so, halt and indicate
the problem somehow.

You might also find the -fstack-usage compiler option useful. This will
emit information in .su files for every .o, containing information on
the size of each function's stack frame. For one project (AVR though,
not MSP430) I wrote a quick and dirty script to assemble a call graph
and figure out the peak stack size:

    http://dlbeer.co.nz/oss/avstack.html

It could probably be modified easily for MSP430 (change $objdump to
"msp430-objdump" for starters), but obviously this technique is only
going to work if your call graph is acyclic.

- Daniel

--
Daniel Beer <[hidden email]>    www.dlbeer.co.nz
IRC: inittab (Freenode)    PGP key: 2048D/160A553B

------------------------------------------------------------------------------
Get your SQL database under version control now!
Version control is standard for application code, but databases havent
caught up. So what steps can you take to put your SQL databases under
version control? Why should you start doing it? Read more to find out.
http://pubads.g.doubleclick.net/gampad/clk?id=49501711&iu=/4140/ostg.clktrk
_______________________________________________
Mspgcc-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/mspgcc-users
Reply | Threaded
Open this post in threaded view
|

Re: Size of global variable

Orlando Arias
In reply to this post by Grant Edwards-6
I would like to add to this list the possibility of a stack/heap
collision if dynamic allocation is being used. I am not sure on the
specifics of the project at hand [I will not ask either], but if the
timer interrupt "stops working" that essentially means something turned
off the interrupt somewhere/the timer configuration got changed. I would
try to use the WDT to reset the device and dump the timer registers upon
power on to see what happened.

On Mon, 2013-07-29 at 21:25 +0000, Grant Edwards wrote:

> On 2013-07-29, ravim <[hidden email]> wrote:
>
> > I will try to do what you have suggested. Issue is we fear that so
> > much is happening in our code too fast (flash write, blacklist check,
> > then communication with different devices etc), we fear we might be
> > corrupting stack somehow with so many global and local variables.
>
> That doesn't really make much sense.  It doesn't matter how many
> things you do or how fast you do them.
>
> Things that will cause intermitten failure after running for a while:
>
>  * stack overflow (or underflow)
>
>  * dereferencing uninitialized pointers
>
>  * buffer overflow (or underflow)
>  
>  * race conditions
>  
> To check for stack overflow, the the easiest thing to do is to
> initialize your stack space with a recognizable pattern. You can then
> periodically check to see how much of the stack still contains that
> initial pattern.  If you can stop program execution when it fails, you
> can check the stack space to make sure that some of it still contains
> the initialization pattern.
>
> > Is there any way through which we can figure out what is actually
> > happening (read the stack etc), why things go smooth for an hour or
> > so. If we change sampling window, timing varies but eventually, it
> > will stop.
>
> If it's not stack overflow, then my _guess_ is that you probably have
> a race condition between forground and interrupt, between two
> interrupts (if you allow interrupts to nest), or between two threads
> (if you've got a multi-threaded system).
>

------------------------------------------------------------------------------
Get your SQL database under version control now!
Version control is standard for application code, but databases havent
caught up. So what steps can you take to put your SQL databases under
version control? Why should you start doing it? Read more to find out.
http://pubads.g.doubleclick.net/gampad/clk?id=49501711&iu=/4140/ostg.clktrk
_______________________________________________
Mspgcc-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/mspgcc-users

signature.asc (205 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Size of global variable

Wayne Uroda-3
In reply to this post by Daniel Beer-3
Hi Daniel,

Yesterday I was looking at just this and to my surprise there was one extra word allocated to ".noinit". I had never seen this before in all my years, and I was almost filling over it with a pattern to measure my stack usage. My point is that one should add the size of bss and data and noinit to find the statically allocated area, or is this incorrect?

At runtime you can find the address of the last of the static data by taking the address of _end, which is provided by the linker script, something like:

void *_end;
UInt16 endAddr = (UInt16)&_end;

(Please let me know if there is a better/preferred way to do this).

You can also get the current stack pointer by doing something like this:
UInt16 sp;

__volatile__ __asm__ (" mov r1, %0" : "=g" (sp));

This tells the compiler to move the stack pointer into the variable sp using any method it chooses (register or memory).

Then you can simply loop from one address to the other and fill with a pattern like 0x55 or similar.

I used this only in a debug environment and wouldn't trust to have it run in a production environment because it was something I threw together real quick.

- Wayne

On 30/07/2013, at 6:22, Daniel Beer <[hidden email]> wrote:

> On Mon, Jul 29, 2013 at 12:56:31PM -0700, ravim wrote:
>> My apologies if I am asking something irrelevant to this forum. We are using
>> mspgcc and mspdebug for our project. We are facing some issues with what we
>> assume might be stack overflow. The timer interrupts stops working after
>> around 2 hours, however device still receives packets. Also, when we reset
>> the device after timer gets stuck, they never turn back on unless we
>> re-install the code.  We are trying to debug.
>>
>> I wanted to know if there is any possible way we can know the size of global
>> variables in the binary? This will help us narrow down a few specifics. We
>> know there is something in TinyOs when we make, it let us know size of
>> global variables, we are looking for something similar in mspdebug.
>>
>> We would really appreciate any help.
>
> Try "size <filename.elf>". Add "data" and "bss" to get the total size of
> statically allocated data. You can also use size on the individual
> object files if you want to narrow down your search, but remember to use
> --common if you need global (non-static) variables to be counted.
>
> Cheers,
> Daniel
>
> --
> Daniel Beer <[hidden email]>    www.dlbeer.co.nz
> IRC: inittab (Freenode)    PGP key: 2048D/160A553B
>
> ------------------------------------------------------------------------------
> Get your SQL database under version control now!
> Version control is standard for application code, but databases havent
> caught up. So what steps can you take to put your SQL databases under
> version control? Why should you start doing it? Read more to find out.
> http://pubads.g.doubleclick.net/gampad/clk?id=49501711&iu=/4140/ostg.clktrk
> _______________________________________________
> Mspgcc-users mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/mspgcc-users

------------------------------------------------------------------------------
Get your SQL database under version control now!
Version control is standard for application code, but databases havent
caught up. So what steps can you take to put your SQL databases under
version control? Why should you start doing it? Read more to find out.
http://pubads.g.doubleclick.net/gampad/clk?id=49501711&iu=/4140/ostg.clktrk
_______________________________________________
Mspgcc-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/mspgcc-users
Reply | Threaded
Open this post in threaded view
|

Re: Size of global variable

Daniel Beer-3
On Tue, Jul 30, 2013 at 08:28:14AM +1000, Wayne Uroda wrote:
> Yesterday I was looking at just this and to my surprise there was one extra word allocated to ".noinit". I had never seen this before in all my years, and I was almost filling over it with a pattern to measure my stack usage. My point is that one should add the size of bss and data and noinit to find the statically allocated area, or is this incorrect?

According to this, .noinit is part of .bss, so it's already counted:

    http://www.nongnu.org/avr-libc/user-manual/mem_sections.html

It would be best to check with Peter, but this does appear to be true,
based on a quick test with mspgcc.

Cheers,
Daniel

--
Daniel Beer <[hidden email]>    www.dlbeer.co.nz
IRC: inittab (Freenode)    PGP key: 2048D/160A553B

------------------------------------------------------------------------------
Get your SQL database under version control now!
Version control is standard for application code, but databases havent
caught up. So what steps can you take to put your SQL databases under
version control? Why should you start doing it? Read more to find out.
http://pubads.g.doubleclick.net/gampad/clk?id=49501711&iu=/4140/ostg.clktrk
_______________________________________________
Mspgcc-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/mspgcc-users
Reply | Threaded
Open this post in threaded view
|

Re: Size of global variable

Peter Bigot-4
In reply to this post by Wayne Uroda-3
The extra word is probably the watchdog timer clear value, which is
initialized on reset.  You can exclude it by using -mdisable-watchdog.
mspgcc uses different sections than AVR, and for mspgcc .noinit is not
merged with .bss.  With the default linker script .noinit is between the
bottom of the stack and the top of .bss.

You can use msp430-objdump -x app.elf to see the list of sections available
and what's in them (at what address).  That information can tell you what's
going to be below the stack, hence the first thing that would get
overwritten when it overruns.

#include <sys/crtld.h> provides declarations for common symbols related to
where things are in memory.  Most of those come from the generic linker
scripts, but a couple (e.g. info section addresses) from the MCU-specific
memory.x linker scripts; all linker scripts are in
installdir/msp430/lib/ldscripts/.

Peter


On Mon, Jul 29, 2013 at 5:28 PM, Wayne Uroda <[hidden email]> wrote:

> Hi Daniel,
>
> Yesterday I was looking at just this and to my surprise there was one
> extra word allocated to ".noinit". I had never seen this before in all my
> years, and I was almost filling over it with a pattern to measure my stack
> usage. My point is that one should add the size of bss and data and noinit
> to find the statically allocated area, or is this incorrect?
>
> At runtime you can find the address of the last of the static data by
> taking the address of _end, which is provided by the linker script,
> something like:
>
> void *_end;
> UInt16 endAddr = (UInt16)&_end;
>
> (Please let me know if there is a better/preferred way to do this).
>
> You can also get the current stack pointer by doing something like this:
> UInt16 sp;
>
> __volatile__ __asm__ (" mov r1, %0" : "=g" (sp));
>
> This tells the compiler to move the stack pointer into the variable sp
> using any method it chooses (register or memory).
>
> Then you can simply loop from one address to the other and fill with a
> pattern like 0x55 or similar.
>
> I used this only in a debug environment and wouldn't trust to have it run
> in a production environment because it was something I threw together real
> quick.
>
> - Wayne
>
> On 30/07/2013, at 6:22, Daniel Beer <[hidden email]> wrote:
>
> > On Mon, Jul 29, 2013 at 12:56:31PM -0700, ravim wrote:
> >> My apologies if I am asking something irrelevant to this forum. We are
> using
> >> mspgcc and mspdebug for our project. We are facing some issues with
> what we
> >> assume might be stack overflow. The timer interrupts stops working after
> >> around 2 hours, however device still receives packets. Also, when we
> reset
> >> the device after timer gets stuck, they never turn back on unless we
> >> re-install the code.  We are trying to debug.
> >>
> >> I wanted to know if there is any possible way we can know the size of
> global
> >> variables in the binary? This will help us narrow down a few specifics.
> We
> >> know there is something in TinyOs when we make, it let us know size of
> >> global variables, we are looking for something similar in mspdebug.
> >>
> >> We would really appreciate any help.
> >
> > Try "size <filename.elf>". Add "data" and "bss" to get the total size of
> > statically allocated data. You can also use size on the individual
> > object files if you want to narrow down your search, but remember to use
> > --common if you need global (non-static) variables to be counted.
> >
> > Cheers,
> > Daniel
> >
> > --
> > Daniel Beer <[hidden email]>    www.dlbeer.co.nz
> > IRC: inittab (Freenode)    PGP key: 2048D/160A553B
> >
> >
> ------------------------------------------------------------------------------
> > Get your SQL database under version control now!
> > Version control is standard for application code, but databases havent
> > caught up. So what steps can you take to put your SQL databases under
> > version control? Why should you start doing it? Read more to find out.
> >
> http://pubads.g.doubleclick.net/gampad/clk?id=49501711&iu=/4140/ostg.clktrk
> > _______________________________________________
> > Mspgcc-users mailing list
> > [hidden email]
> > https://lists.sourceforge.net/lists/listinfo/mspgcc-users
>
>
> ------------------------------------------------------------------------------
> Get your SQL database under version control now!
> Version control is standard for application code, but databases havent
> caught up. So what steps can you take to put your SQL databases under
> version control? Why should you start doing it? Read more to find out.
> http://pubads.g.doubleclick.net/gampad/clk?id=49501711&iu=/4140/ostg.clktrk
> _______________________________________________
> Mspgcc-users mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/mspgcc-users
>

------------------------------------------------------------------------------
Get your SQL database under version control now!
Version control is standard for application code, but databases havent
caught up. So what steps can you take to put your SQL databases under
version control? Why should you start doing it? Read more to find out.
http://pubads.g.doubleclick.net/gampad/clk?id=49501711&iu=/4140/ostg.clktrk
_______________________________________________
Mspgcc-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/mspgcc-users
Reply | Threaded
Open this post in threaded view
|

Re: Size of global variable

Daniel Beer-3
On Mon, Jul 29, 2013 at 05:50:39PM -0500, Peter Bigot wrote:

> The extra word is probably the watchdog timer clear value, which is
> initialized on reset.  You can exclude it by using -mdisable-watchdog.
> mspgcc uses different sections than AVR, and for mspgcc .noinit is not
> merged with .bss.  With the default linker script .noinit is between the
> bottom of the stack and the top of .bss.
>
> You can use msp430-objdump -x app.elf to see the list of sections available
> and what's in them (at what address).  That information can tell you what's
> going to be below the stack, hence the first thing that would get
> overwritten when it overruns.

Hrmm, so it appears then that when "size" says "bss" it actually means
the sum of sections which are marked ALLOC but not LOAD, rather than
literally the .bss section. Is that correct?

Cheers,
Daniel

--
Daniel Beer <[hidden email]>    www.dlbeer.co.nz
IRC: inittab (Freenode)    PGP key: 2048D/160A553B

------------------------------------------------------------------------------
Get your SQL database under version control now!
Version control is standard for application code, but databases havent
caught up. So what steps can you take to put your SQL databases under
version control? Why should you start doing it? Read more to find out.
http://pubads.g.doubleclick.net/gampad/clk?id=49501711&iu=/4140/ostg.clktrk
_______________________________________________
Mspgcc-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/mspgcc-users
Reply | Threaded
Open this post in threaded view
|

Re: Size of global variable

Peter Bigot-4
On Mon, Jul 29, 2013 at 6:06 PM, Daniel Beer <[hidden email]> wrote:

> On Mon, Jul 29, 2013 at 05:50:39PM -0500, Peter Bigot wrote:
> > The extra word is probably the watchdog timer clear value, which is
> > initialized on reset.  You can exclude it by using -mdisable-watchdog.
> > mspgcc uses different sections than AVR, and for mspgcc .noinit is not
> > merged with .bss.  With the default linker script .noinit is between the
> > bottom of the stack and the top of .bss.
> >
> > You can use msp430-objdump -x app.elf to see the list of sections
> available
> > and what's in them (at what address).  That information can tell you
> what's
> > going to be below the stack, hence the first thing that would get
> > overwritten when it overruns.
>
> Hrmm, so it appears then that when "size" says "bss" it actually means
> the sum of sections which are marked ALLOC but not LOAD, rather than
> literally the .bss section. Is that correct?
>
Maybe.  I have one program where the length of the .bss section is 2222
bytes and the length of the .noinit section is 2 bytes, and msp430-size
says it has 2224 bytes in bss.  I couldn't say what else might go into
size's conception of bss length if some of the more esoteric features of
the linker script are exercised.

Peter

------------------------------------------------------------------------------
Get your SQL database under version control now!
Version control is standard for application code, but databases havent
caught up. So what steps can you take to put your SQL databases under
version control? Why should you start doing it? Read more to find out.
http://pubads.g.doubleclick.net/gampad/clk?id=49501711&iu=/4140/ostg.clktrk
_______________________________________________
Mspgcc-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/mspgcc-users