EmbeddedRelated.com
Forums

'Simple' stack problem

Started by David Bonnell November 26, 2007
Hi all,

I am having trouble understanding why my C++ application is
misbehaving.  Object member data is allocated in stack memory, but in
some cases this memory gets overwritten by other (unrelated) function
calls.  This seems to occur regardless of how much space I allocate
for the stack.

I stumbled on the variable that is being overwritten by accident.  Any
ideas on how I should go about tracking this down?
> I stumbled on the variable that is being overwritten by accident. Any > ideas on how I should go about tracking this down?
Place a data watchpoint on the memory location so the debugger breaks when the variable is written to? -- Regards, Richard. + http://www.FreeRTOS.org 14 official architecture ports, 1000 downloads per week. + http://www.SafeRTOS.com Certified by T�V as meeting the requirements for safety related systems.
On Nov 26, 12:38 pm, "FreeRTOS.org" <noem...@address.com> wrote:
> > I stumbled on the variable that is being overwritten by accident. Any > > ideas on how I should go about tracking this down? > > Place a data watchpoint on the memory location so the debugger breaks when > the variable is written to?
Tried, but no luck. I was able to step through the code, and watch the stack pointer grow to overwrite the aforementioned variable (and surrounding memory). ******************** YARRGGH! Found it, and I feel so stupid (i.e. first week of C++ programming course stupid). The project I'm working on is based on old code (presumed to be in good working order). Turns out that the 'object' I'm looking at in memory is temporary, and is used to construct a declared member object in a member initialization list. The member, in turn, uses the default (undeclared) copy constructor...so initialized data isn't being copied over. I defined a real copy constructor and fixed the problem. Now I've got to figure out how a bug like this has existed for 10 years without detection. Groan...I thought my IDE and emulator were playing tricks on me.
On Nov 26, 12:30 pm, David Bonnell <dbonn...@gmail.com> wrote:
> On Nov 26, 12:38 pm, "FreeRTOS.org" <noem...@address.com> wrote: > > > > I stumbled on the variable that is being overwritten by accident. Any > > > ideas on how I should go about tracking this down? > > > Place a data watchpoint on the memory location so the debugger breaks when > > the variable is written to? > > Tried, but no luck. I was able to step through the code, and watch > the stack pointer grow to overwrite the aforementioned variable (and > surrounding memory). > > ******************** > > YARRGGH! Found it, and I feel so stupid (i.e. first week of C++ > programming course stupid). The project I'm working on is based on > old code (presumed to be in good working order). Turns out that the > 'object' I'm looking at in memory is temporary, and is used to > construct a declared member object in a member initialization list. > The member, in turn, uses the default (undeclared) copy > constructor...so initialized data isn't being copied over. I defined > a real copy constructor and fixed the problem. > > Now I've got to figure out how a bug like this has existed for 10 > years without detection. Groan...I thought my IDE and emulator were > playing tricks on me.
so much for unit testing. Obviously the original developer did none. Ed
> so much for unit testing. Obviously the original developer did none. > Ed >
You're not wrong. Code was being written in Borland C++ for DOS (compiler circa 1992). The hardware has changed significantly in that space of time, and the old code has been hacked quite a bit. When it was first written, I'm sure nobody around here had even heard of automated unit testing.
David Bonnell wrote:

> > You're not wrong.
There's something very South Yokshire about that phrase...
On Nov 27, 12:17 pm, David Bonnell <dbonn...@gmail.com> wrote:
> > so much for unit testing. Obviously the original developer did none. > > Ed > > You're not wrong. Code was being written in Borland C++ for DOS > (compiler circa 1992). The hardware has changed significantly in that > space of time, and the old code has been hacked quite a bit. > When it was first written, I'm sure nobody around here had even heard > of automated unit testing.
I wasn't thinking automated. I was thinking he followed this process: code it and if it compiles, throw it over the wall to integration. Hopefully not a medical device. And I never did like C++ garbage collection. Always seemed like the lazy way out on memory management to me. Anyway glad you found and fixed the root problem. Have a great day. Ed
Ed Prochak wrote:
> On Nov 27, 12:17 pm, David Bonnell <dbonn...@gmail.com> wrote: >>> so much for unit testing. Obviously the original developer did none. >>> Ed >> You're not wrong. Code was being written in Borland C++ for DOS >> (compiler circa 1992). The hardware has changed significantly in that >> space of time, and the old code has been hacked quite a bit. >> When it was first written, I'm sure nobody around here had even heard >> of automated unit testing. > > I wasn't thinking automated. I was thinking he followed this process: > code it and if it compiles, throw it over the wall to integration.
That doesn't necessarily have to the case. Sometimes faulty code works correctly and may pass unit tests without a hitch. In that case the effects of the faulty code may only exhibits itself after something (OS, compiler, compiler settings, seemingly unrelated code, new library version...etc) has changed. Recently we had code that ran fine on Linux and passed all unit tests, but a debug build of the same code crashed on Windows. It turned out that a pointer was still being used after freed. On Linux the free operation left the contents of the freed memory intact. With the Windows debug library free operation overwrites the freed memory with a certain pattern, so the bug became visible. Also unit tests do not necessarily find all errors. Even unit tests that have 100% code coverage (which can be quite a hard to achieve), don't necessarily cover all possible execution paths. Covering all execution paths is near impossible for non-trivial code, unless one resorts to (surprisingly expensive) advanced static code analysis tooling like Coverity. Chances are you have written code that has bugs, which when discovered by someone else makes that person wonder if you did bother to test the code in the first place.
> Hopefully not a medical device. And I never did like C++ garbage > collection.
C++ doesn't have garbage collection.
On Nov 26, 11:16 pm, David Bonnell <dbonn...@gmail.com> wrote:
> Hi all, > > I am having trouble understanding why my C++ application is > misbehaving. Object member data is allocated in stack memory, but in > some cases this memory gets overwritten by other (unrelated) function > calls. This seems to occur regardless of how much space I allocate > for the stack. > > I stumbled on the variable that is being overwritten by accident. Any > ideas on how I should go about tracking this down?
What is your device and what software architecture (OS) you are using ? ali
Dombo <dombo@disposable.invalid> wrote:

> Also unit tests do not necessarily find all errors. Even unit tests that > have 100% code coverage (which can be quite a hard to achieve), don't > necessarily cover all possible execution paths. Covering all execution > paths is near impossible for non-trivial code, unless one resorts to > (surprisingly expensive) advanced static code analysis tooling like > Coverity.
With white-box testing, achieving 100% coverage, can be achieved, but does it really pay off? Well written code should be immediately (or withing few seconds) understandable, in the context of having different execution paths. Then there are code (or classes, functions, whatever) for which it is very difficult - or even impossible, or requiring significant infrastructure - to write unit tests with any sense (unit testing of accessors for example isn't probably very useful..). One might argue, that this problem of creating useful unit tests for some pieces of code, is an indication of bad design, but in pratice this happens quite frequently, for example with code doing network I/O.
>> Hopefully not a medical device. And I never did like C++ garbage >> collection. > > C++ doesn't have garbage collection.
This smells like a troll, and very much like it. I would bother.. -- Jyrki Saarinen http://koti.welho.com/jsaari88/