Here's my code:
bool func(const MY_STRUCT *const ptr, some_struct *x, int y)
{
printf("IN: %p\n", ptr); // ok
for (int i = 0; i < y; ++i) {
if (ptr->foo(x[i].key) == 0) {
return false;
}
}
printf("OUT: %p\n", ptr); // ok
return true;
}
void process(void)
{
... ...
for (i = 0; i < num; ++i) {
MY_STRUCT *ptr = obj->GetPtr(); // success
printf("BEFORE: %p\n", ptr); // ok
if (func(ptr, x, y) == false) {
continue;
}
printf("AFTER: %p\n", ptr); // <nil> when compile with -O2
printf("%s", ptr->data); // *** segment fault here ***
}
}
output:
BEFORE: 0x0612d3fa
IN: 0x0612d3fa
OUT: 0x0612d3fa
AFTER: <nil>
segment fault
If I compile above code with -O0, everything works fine.
However, if I compile it with -O2, after the function func
is called, the ptr
become NULL
!
Is this a gcc bug? Did anyone ever have encountered similar bug?
My gcc version is: gcc version 3.4.5 20051201 (Red Hat 3.4.5-2)
There is the (likely) possibility that you have a stack-smasher in func
, which is overwriting ptr
on the caller's stack. Make sure any array or structure accesses in func
remain in bounds. If it weren't for my sour memories of gcc 3.x, I would say that this is nearly certainly what's actually going on. Even so, this is the most likely explanation.
Giving you the benefit of the doubt on that point, if your code is really as posted in your question, then yes, this may be a compiler bug:
printf("BEFORE: %p\n", ptr); // ok
if (func(ptr, x, y)) {
continue;
}
printf("AFTER: %p\n", ptr); // <nil> when compile with -O2
ptr
is passed by value to func
, so it's value in the calling function should not change, regardless of what happens within func
.
However, you're using a truly ancient compiler; even if you report this bug, nothing will ever come of it. It is quite likely that whatever caused this has long since changed in gcc
. Try a newer version or a different compiler.