On Sat, Nov 28, 2009 at 4:13 PM, Paul Edwards <mutazi...@gmail.com> wrote:
> I think I have found a bug in gcc, that still exists in gcc 4.4
>
> I found the problem on 3.2.3 though.
>
> While MVS and VM have basically been working fine, when I did
> the port to MUSIC/SP I started getting strange compilation failures.
>
> Initializing the stack to NULs made the problem go away, but I
> persisted, and instead initialized the stack to x'01' to try to get
> consistent failures.
>
> Even with that, and the malloced memory initialized to consistent
> garbage, I still didn't get the desired consistency in failures.
> But it was consistent enough that I could just run it 6 times and
> see if there were any failures.
>
>
> Anyway, I tracked down the particular malloc() which gave changed
> behaviour depending on whether the malloc() did a memory initialization
> to NULs or not.

Well, GC hands out non-zeroed memory - the callers are responsible
for initializing it.  So the fix below is not a fix but papering over an
issue elswhere.

Richard.

> It's this one (showing 3.2.3):
>
> C:\devel\gcc\gcc>cvs diff -l -c15
> cvs diff: Diffing .
> Index: ggc-page.c
> ===================================================================
> RCS file: c:\cvsroot/gcc/gcc/ggc-page.c,v
> retrieving revision 1.1.1.1
> diff -c -1 -5 -r1.1.1.1 ggc-page.c
> *** ggc-page.c  15 Feb 2006 10:22:25 -0000      1.1.1.1
> --- ggc-page.c  28 Nov 2009 14:13:41 -0000
> ***************
> *** 640,670 ****
>  #ifdef USING_MALLOC_PAGE_GROUPS
>   else
>     {
>       /* Allocate a large block of memory and serve out the aligned
>        pages therein.  This results in much less memory wastage
>        than the traditional implementation of valloc.  */
>
>       char *allocation, *a, *enda;
>       size_t alloc_size, head_slop, tail_slop;
>       int multiple_pages = (entry_size == G.pagesize);
>
>       if (multiple_pages)
>       alloc_size = GGC_QUIRE_SIZE * G.pagesize;
>       else
>       alloc_size = entry_size + G.pagesize - 1;
> !       allocation = xmalloc (alloc_size);
>
>       page = (char *) (((size_t) allocation + G.pagesize - 1) &
> -G.pagesize);
>       head_slop = page - allocation;
>       if (multiple_pages)
>       tail_slop = ((size_t) allocation + alloc_size) & (G.pagesize - 1);
>       else
>       tail_slop = alloc_size - entry_size - head_slop;
>       enda = allocation + alloc_size - tail_slop;
>
>       /* We allocated N pages, which are likely not aligned, leaving
>        us with N-1 usable pages.  We plan to place the page_group
>        structure somewhere in the slop.  */
>       if (head_slop >= sizeof (page_group))
>       group = (page_group *)page - 1;
>       else
> --- 640,670 ----
>  #ifdef USING_MALLOC_PAGE_GROUPS
>   else
>     {
>       /* Allocate a large block of memory and serve out the aligned
>        pages therein.  This results in much less memory wastage
>        than the traditional implementation of valloc.  */
>
>       char *allocation, *a, *enda;
>       size_t alloc_size, head_slop, tail_slop;
>       int multiple_pages = (entry_size == G.pagesize);
>
>       if (multiple_pages)
>       alloc_size = GGC_QUIRE_SIZE * G.pagesize;
>       else
>       alloc_size = entry_size + G.pagesize - 1;
> !       allocation = xcalloc (1, alloc_size);
>
>       page = (char *) (((size_t) allocation + G.pagesize - 1) &
> -G.pagesize);
>       head_slop = page - allocation;
>       if (multiple_pages)
>       tail_slop = ((size_t) allocation + alloc_size) & (G.pagesize - 1);
>       else
>       tail_slop = alloc_size - entry_size - head_slop;
>       enda = allocation + alloc_size - tail_slop;
>
>       /* We allocated N pages, which are likely not aligned, leaving
>        us with N-1 usable pages.  We plan to place the page_group
>        structure somewhere in the slop.  */
>       if (head_slop >= sizeof (page_group))
>       group = (page_group *)page - 1;
>       else
>
>
> I suspect that it has stayed hidden for so long because most people
> probably have this mmap_anon:
>
> /* Define if mmap can get us zeroed pages using MAP_ANON(YMOUS). */
> #undef HAVE_MMAP_ANON
>
>
> #ifdef HAVE_MMAP_ANON
> # undef HAVE_MMAP_DEV_ZERO
>
> # include <sys/mman.h>
> # ifndef MAP_FAILED
> #  define MAP_FAILED -1
> # endif
> # if !defined (MAP_ANONYMOUS) && defined (MAP_ANON)
> #  define MAP_ANONYMOUS MAP_ANON
> # endif
> # define USING_MMAP
>
> #endif
>
> #ifndef USING_MMAP
> #define USING_MALLOC_PAGE_GROUPS
> #endif
>
>
> Seems pretty clear that zeroed pages are required.
>
> Looking at the code above and below this block, it uses xcalloc
> instead.
>
> It will take a couple of days to confirm that this is the last
> presumed bug affecting the MUSIC/SP port.
>
> In the meantime, can someone confirm that this code is wrong,
> and that xcalloc is definitely required?
>
> I had a look at the gcc4 code, and it is calling XNEWVEC which
> is also using xmalloc instead of xcalloc, so I presume it is still
> a problem today, under the right circumstances.
>
> It took about a week to track this one down.  :-)
>
> One problem I have had for years, even on the MVS port, is that
> I need to use -Os to get the exact same register selection on the
> PC as the mainframe.  -O0 and -O2 get slightly different register
> allocations, although all versions of the code are correct.  If I'm
> lucky, this fix may make that problem go away, but as I said,
> it'll take a couple of days before the results are in, as each build
> takes about 2 hours (partly because i need to use -Os for
> consistency).
>
> Thanks.  Paul.
>
>

Reply via email to