gcc 4.3.0 bug: ASSERT on all x64 apps: "reachability contraints not satisfiable"
From derek.br...@gmail.com on February 15, 2009 17:11:00
ASSERT with gcc 4.3.0 on all x64 apps: "reachability contraints not satisfiable"
SYSLOG_ERROR: Application hello64 (1982). Internal Error Internal DynamoRIO Error: heap.c:474 heap_allowable_region_start <= must_reach_region_start && "PR 215395 reachability contraints not satisfiable"
This is due to gcc 4.3.0, even at -O0, considering "ptr - const < ptr" (in REACHABLE_32BIT_END()) to always be true, which is an invalid optimization as it ignores underflow. I have a simple test app that shows the problem very clearly, inlined below with objdump -dS. I don't see any gcc options to affect this optimization.
The disturbing aspect is I don't know what other bugs this gcc behavior is going to cause: certainly throughout win32/os.c we watch for overflow via "if (pb + mbi.RegionSize < pb)".
The toolchain compiler gcc 4.1.2 does not have the buggy behavior of course.
/work/dr/test/gcc-underflow-bug.c: #include <stdio.h>
int main() { unsigned char ptr1 = (unsigned char *) 0x0000000071542000; unsigned char *ptr3 = ptr1 - 0x80000000; / 0xfffffffff1542000 */ if (ptr3 < ptr1) printf("ptr3 less than\n"); if ((ptr1 - 0x80000000) < ptr1) printf("temp less than\n"); }
#if 0 gcc 4.3.0 -O0: int main() { 4004cc: 55 push %rbp 4004cd: 48 89 e5 mov %rsp,%rbp 4004d0: 48 83 ec 20 sub $0x20,%rsp unsigned char ptr1 = (unsigned char *) 0x0000000071542000; 4004d4: 48 c7 45 f0 00 20 54 movq $0x71542000,-0x10(%rbp) 4004db: 71 unsigned char *ptr3 = ptr1 - 0x80000000; / 0xfffffffff1542000 */ 4004dc: 48 8b 45 f0 mov -0x10(%rbp),%rax 4004e0: 48 05 00 00 00 80 add $0xffffffff80000000,%rax 4004e6: 48 89 45 f8 mov %rax,-0x8(%rbp) if (ptr3 < ptr1) 4004ea: 48 8b 45 f8 mov -0x8(%rbp),%rax 4004ee: 48 3b 45 f0 cmp -0x10(%rbp),%rax 4004f2: 73 0a jae 4004fe <main+0x32> printf("ptr3 less than\n"); 4004f4: bf 08 06 40 00 mov $0x400608,%edi 4004f9: e8 ba fe ff ff callq 4003b8 puts@plt if ((ptr1 - 0x80000000) < ptr1) printf("temp less than\n"); 4004fe: bf 17 06 40 00 mov $0x400617,%edi 400503: e8 b0 fe ff ff callq 4003b8 puts@plt } 400508: c9 leaveq 400509: c3 retq
/build/toolchain/lin32/gcc-4.1.2-2/bin/x86_64-linux-gcc: if ((ptr1 - 0x80000000) < ptr1) 4004ca: 48 8b 45 f0 mov -0x10(%rbp),%rax 4004ce: 48 05 00 00 00 80 add $0xffffffff80000000,%rax 4004d4: 48 3b 45 f0 cmp -0x10(%rbp),%rax 4004d8: 73 0a jae 4004e4 <main+0x4c> printf("temp less than\n"); 4004da: bf db 05 40 00 mov $0x4005db,%edi 4004df: e8 d4 fe ff ff callq 4003b8 puts@plt } #endif
Original issue: http://code.google.com/p/dynamorio/issues/detail?id=14