|
From: Sebastian K. <Seb...@so...> - 2005-09-26 16:59:52
|
Julian Seward wrote:
> On Sunday 25 September 2005 11:08, Erik de Castro Lopo wrote:
>
>>Hi all,
>>
>>I'm getting this:
>>
>> ==11233== Address 0x52BFE690 is just below %esp. Possibly a bug in
>>GCC/G++ ==11233== v 2.96 or 3.0.X. To suppress, use:
>>--workaround-gcc296-bugs=yes
>>
>>I'm using gcc-4.0.1. Is this message stil relevant for this compiler?
>
>
> Yes. Any access at all below %esp on an x86 is a unconditionally bug
> which could potentially crash your program. If you found such a
> thing and can pin it on gcc, then it's a gcc bug. Such things have
> happened at least twice before: gcc-2.96 (structure returns, a real
> dog) and in a gcc-3.0.0 prerelease (scheduling problem, it moved
> stack frame removal code around incorrectly). That said, I have
> not heard of any such problem in gcc 3.0.0 or later.
There is also funny big in gcc 3.2.x (tested quite a few versions, including
long mainained GCC 3.2.3 in RHEL). When const automatic objects are used,
destructors are not allways called when leaving scope. So when object was
registering itself in some global structure on construction, and
deregistering on destruction, then such undestructed but erased objects
caused funny effects when some operation was later performed on that global
structure.
One of the symptoms was 'Address 0xDEADBEEF is just below %esp'.
rgds
Sebastian Kaliszewski
PS: here's the demonstrator code. Under proper compiler final count should
be of course 0, but under GCC 3.2.x it's 2 (so 2 undead objects).
#include <iostream>
using namespace std;
struct cnt
{
static unsigned count;
static unsigned inst;
unsigned num;
cnt(): num(inst)
{ ++count; ++inst; cout << " (+)" << num << flush; }
cnt(const cnt&): num(inst)
{ ++count; ++inst; cout << " (*)" << num << flush; }
~cnt() { --count; cout << " (-)" << num << flush; }
};
unsigned cnt::count = 0;
unsigned cnt::inst = 0;
const cnt pass(const cnt p)
{ return p;}
cnt multipass(cnt p)
{ return pass(pass(pass(p))); }
int main()
{
cout << "Testing compiler validity..." << endl;
{
cnt c = cnt();
cnt r = multipass(c);
}
cout << endl;
cout << "cnt::count = " << cnt::count << endl;
return cnt::count;
}
|