[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