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);
}

Reply via email to