On Sat, 31 Dec 2011, Mark Kettenis wrote: > Execution of the test randomly fails for me on OpenBSD/amd64. Looking > at the code, it seems it is doing an out-of-bounds array access. For > refernce I've copied the code of the testcase below. As you can see > there's a foo(0) call in main(). Therefore > > struct foo **upper = &as->x[rank * 8 - 1]; > > becomes > > struct foo **upper = &as->x[-1]; > > so upper points to an address before the malloc()'ed memory. Then > when the code does > > *upper = 0; > > this generates a SIGSEGV, if the malloc()'ed memory happens to lie > right at the start of a page. I suppose that may never happen on some > platforms (Linux?) since many malloc() implementations will use the > start of a page for their own bookkeeping. > > I don't really understand what the testcase is testing. Richard, can > you perhaps shed some light on this?
The testcase was added when trying to fix PR32921, I do not remember whether it was relevant that an out-of-bounds array access occured (but I suppose it was so). It was a miscompile, so a runtime testcase is required. I suppose changing the testcase to do &as->x[rank * 8 - 8] and pass in rank == 1 would make it fail similarly on rev. 129484 (or better make it &as->x[rank * 2 = 2]). Richard. > Thanks, > > Mark > > --- > > extern void abort(void); > > struct foo { > int rank; > char *name; > }; > > struct mem { > struct foo *x[4]; > }; > > void __attribute__((noinline)) bar(struct foo **f) > { > *f = __builtin_malloc(sizeof(struct foo)); > } > struct foo * foo(int rank) > { > void *x = __builtin_malloc(sizeof(struct mem)); > struct mem *as = x; > struct foo **upper = &as->x[rank * 8 - 1]; > *upper = 0; > bar(upper); > return *upper; > } > > int main() > { > if (foo(0) == 0) > abort (); > return 0; > } > > -- Richard Guenther <rguent...@suse.de> SUSE / SUSE Labs SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746 GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer