I ran into a very weird problem today. Long story short, my function returns one value, the caller gets a different value. Somewhere around my code I have a call to:
Message* m = NULL;
m = connection_receive(c);
Where connection_receive is defined as follows:
Message* connection_receive(Connection* c)
{
Message* k;
if (c->state == CON_STATE_AUTHENTICATED)
{
pthread_mutex_lock(&c->mutex_in);
if (g_queue_is_empty(c->in))
k = NULL;
else
k = (Message*)g_queue_pop_head(c->in);
pthread_mutex_unlock(&c->mutex_in);
/* Until here, k is reachable and contains the correct data. */
return k;
}
else
return NULL;
}
Here's a gdb run, I stopped right before the return and right after the assignment:
222 return k;
(gdb) p k
$1 = (Message *) 0x7ffff0000950
(gdb) n
226 }
(gdb) n
main () at src/main.c:57
57 if (m)
(gdb) p m
$2 = (Message *) 0xfffffffff0000950
Of course, if we try to access 0xfffffffff0000950 we'll get a segmentation fault.
If I change the function and instead of returning a value, using a second parameter to pass the value it works, but I would like to know what went wrong on this one.
Thank you very much.
EDIT: This works, but it's not convenient. And I would also like to know why such strange error is happening.
void connection_receive2(Connection* c, Message** m)
{
if (c->state == CON_STATE_AUTHENTICATED)
{
pthread_mutex_lock(&c->mutex_in);
if (g_queue_is_empty(c->in))
*m = NULL;
else
*m = (Message*)g_queue_pop_head(c->in);
pthread_mutex_unlock(&c->mutex_in);
}
else
*m = NULL;
}
EDIT2: Solved. Thanks all. The problem was a typo on the header file. I can't use -Werror because I need to do things which raise some warnings, and in a large make output and large header I missed it.
finshowed one return value and the variable it was stored into showed another. A recompile fixed it for me (didn't even change the source at all); best I can guess is a dependent object file didn't get recompiled, otherwise possibly a (rarely encountered) bug in gcc.