3

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)

iCoder
  • 456
  • 3
  • 11
  • You may have a bug in your "do something" code in `func` which is trashing the caller's `ptr` – Paul R Oct 28 '11 at 10:35
  • 6
    Maybe it is a compiler's bug, but before start searching for it, run your program under valgrind, and make sure there are no memory access problems. Maybe you have a stack corruption somewhere. – BЈовић Oct 28 '11 at 10:35
  • 7
    It's 99.999% bug in your code. Please post more code and real usage + output of the execution. – Kiril Kirov Oct 28 '11 at 10:35
  • 16
    3rd rule of programming: "Always suspect the bug is in YOUR code, not someone else's or the compiler" – Mitch Wheat Oct 28 '11 at 10:36
  • What happens if you do not call `func`? – Michel Oct 28 '11 at 10:39
  • 5
    A sidenote: many bugs in GCC have been fixed since 2005. How does this code behave under newer compiler? – Tadeusz A. Kadłubowski Oct 28 '11 at 10:51
  • 7
    What I don't get is, your snipet for `func` always returns `true`, and the part you say crashes should only be called if `func` returns `false`. – wormsparty Oct 28 '11 at 11:12
  • 2
    Can you produce a runnable example that reproduces the error? The code you've posted will never execute the problematic line, so it's impossible to guess what might be wrong with the real code. – Mike Seymour Oct 28 '11 at 11:51

2 Answers2

1

Whatever bugs your compiler may or may not have, if you see the described problem in the code you posted, then your GCC is broken at any optimization level.

The problematic line of code should never be reached at all.

func always returns true, and if it returns true, the last part of the loop body is skipped.

If you suspect a compiler bug, start by writing a code sample that reproduces it.

When we don't know what your actual code looks like, it's impossible for us to guess at whether GCC's behavior is correct or not.

jalf
  • 243,077
  • 51
  • 345
  • 550
  • I assume that there's a `return false` somewhere in `// do something`; the alternative is simply too terrifying. – Stephen Canon Oct 28 '11 at 12:42
  • Quite likely, but if we don't know where it is, and what else might happen, it's impossible to guess at what the correct behavior should be – jalf Oct 28 '11 at 12:47
1

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.

Stephen Canon
  • 103,815
  • 19
  • 183
  • 269
  • Thanks. I will try to compile it with gcc4 later and post the result. The weird thing is that `ptr` is always `NULL`. I think if something in `func` rewrite `ptr`'s value, it will be a random value, almost no posible be 0. – iCoder Oct 28 '11 at 14:16