Hi all,
Le 14/05/2016 14:06, Arthur Țițeică a écrit :
În ziua de sâmbătă, 14 mai 2016, la 13:57:35 EEST, Willy Tarreau a scris:
What is the most important is to report this to the gcc maintainers so that
they can fix the bug. The fix will naturally flow into the distros.
I understand this and of course I could try to fill a bug on their side but
the gcc stuff is a bit out of my league.
After spending some time on this, I'm now able to produce a minimal test
case.
$ gcc-6 -O2 -o debug debug.c && ./debug
0
=> here we have an issue, as it shouldn't be 0
$ gcc-6 -O2 -DDEBUG -o debug debug.c && ./debug
7f000001
7f000001
=> Suddenly, everything works
And now, what happens with this debug code when -fno-tree-sra is used ?
$ gcc-6 -O2 -fno-tree-sra -DDEBUG -o debug debug.c && ./debug
7f000001
0
=> It still doesn't work :-( So, disabling "tree-sra" doesn't guarantee
the right behaviour.
I also attach a debug2.c example, which is also disturbing. It is the
same code, but adds a local variable. Depending on the code order,
strange things happen (looks like a memory alignment issue).
For example :
$ gcc-6 -O2 -o debug2 debug2.c && ./debug2
0
fd7f0000
Note : my tests were made on a Debian SID with the gcc-6 package.
--
Cyril Bonté
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
struct dbg_listener {
struct sockaddr_storage addr;
};
int main(int argc, char **argv)
{
struct dbg_listener *l;
struct sockaddr_storage ss, *ss2, ss3;
memset(&ss3, 0, sizeof(ss3));
ss3.ss_family = AF_INET;
((struct sockaddr_in *)&ss3)->sin_addr.s_addr = inet_addr("127.0.0.1");
ss2 = &ss3;
ss = *ss2;
l = calloc(1, sizeof(*l));
l->addr = ss;
#ifdef DEBUG
printf("%x\n", ntohl(((struct sockaddr_in *)(&ss))->sin_addr.s_addr));
#endif
printf("%x\n", ntohl(((struct sockaddr_in *)(&l->addr))->sin_addr.s_addr));
exit(0);
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
struct dbg_listener {
struct sockaddr_storage addr;
};
int main(int argc, char **argv)
{
struct dbg_listener *l;
struct sockaddr_storage ss, *ss2, ss3;
struct sockaddr_storage addr;
memset(&ss3, 0, sizeof(ss3));
ss3.ss_family = AF_INET;
((struct sockaddr_in *)&ss3)->sin_addr.s_addr = inet_addr("127.0.0.1");
ss2 = &ss3;
ss = *ss2;
addr = ss;
l = calloc(1, sizeof(*l));
l->addr = ss;
#ifdef DEBUG
printf("%x\n", ntohl(((struct sockaddr_in *)(&ss))->sin_addr.s_addr));
#endif
printf("%x\n", ntohl(((struct sockaddr_in *)(&l->addr))->sin_addr.s_addr));
printf("%x\n", ntohl(((struct sockaddr_in *)(&addr))->sin_addr.s_addr));
exit(0);
}