[Bug optimization/14863] [3.4/3.5 regression] unit-at-a-time causes miscompilation
1319 at bot dot ru
gcc-bugzilla@gcc.gnu.org
Sun Apr 11 01:06:00 GMT 2004
------- Additional Comments From 1319 at bot dot ru 2004-04-10 22:16 -------
I have just figured out that delete() segfaults because new() returned wrong
pointer; it can be shown using overloaded operators new() and delete(). This
happens because there is a memory corruption somewhere...
To figure out where I used custom new() and memprotect():
(put this code before main(), and add #include <sys/mman.h>)
void *pool;
int last = 1;
#define NMAX 0x80
#define NSIZ 0x10000
void* operator new(size_t size)
{
void *p;
if (!pool) {
// allocate page aligned NMAX*NSIZ bytes of memory
// (assume pagesize = 0x1000)
pool = (void *) (0xFFFFF000 &
((long) calloc (1, NMAX*NSIZ) + 0xFFF));
mprotect (pool, NMAX*NSIZ, PROT_NONE);
}
if (last >= (NMAX-1)) {
fprintf (stderr, "out of memory");
abort ();
}
// (1) guards access below returned pointer
//p = (void *) ((long) pool + (last++)*NSIZ);
// (2) guards access above returned pointer
p = (void *) ((long) pool + (last++)*NSIZ - ((size + 3) & 0xFFFFFFFC));
mprotect ((void *) ((long) p & 0xFFFFF000), size, PROT_READ|PROT_WRITE);
// test of (1)
//*((char *) p - 1) = 0; /* segfault */
// test of (2)
//*((char *) p + size + 3) = 0; /* segfault */
fprintf (stderr, "new: size = %lu, p = %p\n", size, p);
return p;
//return calloc (1, size);
}
void operator delete(void* p)
{
fprintf (stderr, "delete: %p\n", p);
//free (p);
}
This new() returns pointer to memory block surrounded by pages with no access.
Alas protection can be set only for entire page, so there is two versions: (1)
places block at beginning of page with rw acces, and (2) at end of it.
(1) does not work, it seems that there is no wrong memory references below
allocated blocks. But (2) works as expected, with -O1 -funit-at-a-time --param
large-function-insns=1000 program gets segfault in new place:
Program received signal SIGSEGV, Segmentation fault.
0x08056d6e in Engine<1, int, Dynamic>::performDestroy<IntervalIterator>
(this=0x4042cfec, killBegin=@0x9, killEnd=@0x9)
at pr14863.cc:4196
4196 return tmp;
(gdb) where
#0 0x08056d6e in Engine<1, int, Dynamic>::performDestroy<IntervalIterator>
(this=0x4042cfec, killBegin=@0x9, killEnd=@0x9)
at pr14863.cc:4196
#1 0x08056f35 in Engine<1, int, Dynamic>::performDestroy<Interval<1> >
(this=0x9, killList=@0xbffff530, offsetFlag=false)
at pr14863.cc:12135
#2 0x08056f71 in Engine<1, int, Dynamic>::destroy<Interval<1> > (this=0x9,
killList=@0x9) at pr14863.cc:4513
#3 0x080571f0 in Particles<MPDynamicUniform>::performDestroy (this=0xbffff7b0,
pid=-1073744704, renum=true) at pr14863.cc:11218
#4 0x0804fb35 in main (argc=1, argv=0xbffff994) at pr14863.cc:14496
(gdb) list
14496 P.performDestroy();
14497 DynamicArray < Vector < 2, int >, MultiPatch < DynamicTag,
Dynamic > >a3;
14498 Interval < 1 > empty;
14499 DynamicLayout layout(empty, 1);
14500 a3.initialize(layout);
14501 a3.create(20);
14502 }
(gdb) list 4196
4191 return tmp;
4192 }
4193 This_t operator--(int) {
4194 This_t tmp(*this);
4195 RCBPtr_t::operator--();
4196 return tmp;
4197 }
4198 This_t operator+(ptrdiff_t i) const {
4199 This_t ret(*this);
4200 ret += i;
(gdb) q
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14863
More information about the Gcc-bugs
mailing list