<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE bugzilla SYSTEM "http://sourceware.org/bugzilla/bugzilla.dtd">

<bugzilla version="4.0.10"
          urlbase="http://sourceware.org/bugzilla/"
          
          maintainer="overseers@sourceware.org"
>

    <bug>
          <bug_id>14562</bug_id>
          
          <creation_ts>2012-09-07 23:49:00 +0000</creation_ts>
          <short_desc>threaded programs with x32 abi randomly crash with arena.c:661: heap_trim: Assertion `p-&gt;size == (0|0x1)&apos; failed</short_desc>
          <delta_ts>2012-09-26 18:33:18 +0000</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>glibc</product>
          <component>malloc</component>
          <version>2.16</version>
          <rep_platform>All</rep_platform>
          <op_sys>All</op_sys>
          <bug_status>RESOLVED</bug_status>
          <resolution>FIXED</resolution>
          
          
          <bug_file_loc>https://bugs.gentoo.org/show_bug.cgi?id=394175</bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords></keywords>
          <priority>P2</priority>
          <bug_severity>normal</bug_severity>
          <target_milestone>2.16</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter name="Mike Frysinger">vapier</reporter>
          <assigned_to name="H.J. Lu">hjl.tools</assigned_to>
          <cc>drepper.fsp</cc>
    
    <cc>dschepler</cc>
    
    <cc>hjl.tools</cc>
          <cf_gcchost></cf_gcchost>
          <cf_gcctarget></cf_gcctarget>
          <cf_gccbuild></cf_gccbuild>
          

      

      

      

          <long_desc isprivate="0">
            <commentid>57306</commentid>
            <who name="Mike Frysinger">vapier</who>
            <bug_when>2012-09-07 23:49:32 +0000</bug_when>
            <thetext>test case:
- use glibc-2.16 with x32 abi
- get a bunch of files (like ~150; perl man pages are a sample input)
- run `bzip2 -k &lt;files&gt;`
- run `pbzip2 -k -f &lt;files&gt; -p4`

see crash:
pbzip2: arena.c:661: heap_trim: Assertion `p-&gt;size == (0|0x1)&apos; failed.

this has happened with a other threaded programs (git &amp; squashfs); see gentoo bug for some more details</thetext>
          </long_desc>
          <long_desc isprivate="0">
            <commentid>57307</commentid>
            <who name="H.J. Lu">hjl.tools</who>
            <bug_when>2012-09-08 00:42:46 +0000</bug_when>
            <thetext>hjl/x32/release/2.15 branch is OK.</thetext>
          </long_desc>
          <long_desc isprivate="0">
            <commentid>57308</commentid>
            <who name="H.J. Lu">hjl.tools</who>
            <bug_when>2012-09-08 01:03:14 +0000</bug_when>
            <thetext>Copy malloc from hjl/x32/release/2.15 branch makes the
problem goes away.</thetext>
          </long_desc>
          <long_desc isprivate="0">
            <commentid>57310</commentid>
            <who name="H.J. Lu">hjl.tools</who>
            <bug_when>2012-09-08 04:03:06 +0000</bug_when>
            <thetext>The bug is triggered by MALLOC_ALIGNMENT=16.</thetext>
          </long_desc>
          <long_desc isprivate="0">
            <commentid>57312</commentid>
            <who name="H.J. Lu">hjl.tools</who>
            <bug_when>2012-09-08 14:52:34 +0000</bug_when>
            <thetext>663	    assert(p-&gt;size == (0|PREV_INUSE)); /* must be fencepost */
(gdb) p p
$34 = (mchunkptr) 0xf55feff8
(gdb) 

p isn&apos;t 16-byte aligned.</thetext>
          </long_desc>
          <long_desc isprivate="0">
            <commentid>57313</commentid>
            <who name="H.J. Lu">hjl.tools</who>
            <bug_when>2012-09-08 15:30:13 +0000</bug_when>
            <thetext>The size of top chunk must be a multiple of MALLOC_ALIGNMENT.
But _int_new_arena has

  /* Set up the top chunk, with proper alignment. */
  ptr = (char *)(a + 1);
  misalign = (unsigned long)chunk2mem(ptr) &amp; MALLOC_ALIGN_MASK;
  if (misalign &gt; 0)
    ptr += MALLOC_ALIGNMENT - misalign;
  top(a) = (mchunkptr)ptr;
  set_head(top(a), (((char*)h + h-&gt;size) - ptr) | PREV_INUSE);

It doesn&apos;t check size requirement.</thetext>
          </long_desc>
          <long_desc isprivate="0">
            <commentid>57314</commentid>
            <who name="H.J. Lu">hjl.tools</who>
            <bug_when>2012-09-08 20:43:47 +0000</bug_when>
            <thetext>I am testing this patch:

diff --git a/malloc/arena.c b/malloc/arena.c
index f88b41d..ac5afc4 100644
--- a/malloc/arena.c
+++ b/malloc/arena.c
@@ -655,14 +655,22 @@ heap_trim(heap_info *heap, size_t pad)
   mchunkptr top_chunk = top(ar_ptr), p, bck, fwd;
   heap_info *prev_heap;
   long new_size, top_size, extra;
+  unsigned long misalign;
 
   /* Can this heap go away completely? */
   while(top_chunk == chunk_at_offset(heap, sizeof(*heap))) {
     prev_heap = heap-&gt;prev;
     p = chunk_at_offset(prev_heap, prev_heap-&gt;size - (MINSIZE-2*SIZE_SZ));
+    /* fencepost must be properly aligned.  */
+    misalign = ((unsigned long) p) &amp; MALLOC_ALIGN_MASK;
+    if (misalign &gt; 0)
+      {
+	p = (mchunkptr)(((unsigned long) p) &amp; ~MALLOC_ALIGN_MASK);
+	misalign = MALLOC_ALIGNMENT - misalign;
+      }
     assert(p-&gt;size == (0|PREV_INUSE)); /* must be fencepost */
     p = prev_chunk(p);
-    new_size = chunksize(p) + (MINSIZE-2*SIZE_SZ);
+    new_size = chunksize(p) + (MINSIZE-2*SIZE_SZ) + misalign;
     assert(new_size&gt;0 &amp;&amp; new_size&lt;(long)(2*MINSIZE));
     if(!prev_inuse(p))
       new_size += p-&gt;prev_size;</thetext>
          </long_desc>
          <long_desc isprivate="0">
            <commentid>57315</commentid>
            <who name="H.J. Lu">hjl.tools</who>
            <bug_when>2012-09-08 20:48:37 +0000</bug_when>
            <thetext>This is the right one:

diff --git a/malloc/arena.c b/malloc/arena.c
index f88b41d..8d52109 100644
--- a/malloc/arena.c
+++ b/malloc/arena.c
@@ -655,14 +655,18 @@ heap_trim(heap_info *heap, size_t pad)
   mchunkptr top_chunk = top(ar_ptr), p, bck, fwd;
   heap_info *prev_heap;
   long new_size, top_size, extra;
+  unsigned long misalign;
 
   /* Can this heap go away completely? */
   while(top_chunk == chunk_at_offset(heap, sizeof(*heap))) {
     prev_heap = heap-&gt;prev;
     p = chunk_at_offset(prev_heap, prev_heap-&gt;size - (MINSIZE-2*SIZE_SZ));
+    /* fencepost must be properly aligned.  */
+    misalign = ((unsigned long) p) &amp; MALLOC_ALIGN_MASK;
+    p = (mchunkptr)(((unsigned long) p) &amp; ~MALLOC_ALIGN_MASK);
     assert(p-&gt;size == (0|PREV_INUSE)); /* must be fencepost */
     p = prev_chunk(p);
-    new_size = chunksize(p) + (MINSIZE-2*SIZE_SZ);
+    new_size = chunksize(p) + (MINSIZE-2*SIZE_SZ) + misalign;
     assert(new_size&gt;0 &amp;&amp; new_size&lt;(long)(2*MINSIZE));
     if(!prev_inuse(p))
       new_size += p-&gt;prev_size;</thetext>
          </long_desc>
          <long_desc isprivate="0">
            <commentid>57316</commentid>
            <who name="H.J. Lu">hjl.tools</who>
            <bug_when>2012-09-08 20:58:39 +0000</bug_when>
            <thetext>This one is better:

diff --git a/malloc/arena.c b/malloc/arena.c
index f88b41d..4727d1e 100644
--- a/malloc/arena.c
+++ b/malloc/arena.c
@@ -654,15 +654,18 @@ heap_trim(heap_info *heap, size_t pad)
   unsigned long pagesz = GLRO(dl_pagesize);
   mchunkptr top_chunk = top(ar_ptr), p, bck, fwd;
   heap_info *prev_heap;
-  long new_size, top_size, extra;
+  long new_size, top_size, extra, misalign;
 
   /* Can this heap go away completely? */
   while(top_chunk == chunk_at_offset(heap, sizeof(*heap))) {
     prev_heap = heap-&gt;prev;
     p = chunk_at_offset(prev_heap, prev_heap-&gt;size - (MINSIZE-2*SIZE_SZ));
+    /* fencepost must be properly aligned.  */
+    misalign = ((long) p) &amp; MALLOC_ALIGN_MASK;
+    p = (mchunkptr)(((unsigned long) p) &amp; ~MALLOC_ALIGN_MASK);
     assert(p-&gt;size == (0|PREV_INUSE)); /* must be fencepost */
     p = prev_chunk(p);
-    new_size = chunksize(p) + (MINSIZE-2*SIZE_SZ);
+    new_size = chunksize(p) + (MINSIZE-2*SIZE_SZ) + misalign;
     assert(new_size&gt;0 &amp;&amp; new_size&lt;(long)(2*MINSIZE));
     if(!prev_inuse(p))
       new_size += p-&gt;prev_size;</thetext>
          </long_desc>
          <long_desc isprivate="0">
            <commentid>57329</commentid>
            <who name="H.J. Lu">hjl.tools</who>
            <bug_when>2012-09-09 18:29:59 +0000</bug_when>
            <thetext>Please try hjl/pr14562/2.16 branch.</thetext>
          </long_desc>
          <long_desc isprivate="0">
            <commentid>57337</commentid>
            <who name="Mike Frysinger">vapier</who>
            <bug_when>2012-09-10 05:42:25 +0000</bug_when>
            <thetext>(In reply to comment #9)

seems to be the same fix as in comment #8 which i&apos;ve been running locally.  it fixed the known bugs i was hitting, and haven&apos;t seen any new ones related to this.  there are other bugs, but those are porting issues :).</thetext>
          </long_desc>
          <long_desc isprivate="0">
            <commentid>57344</commentid>
            <who name="Daniel Schepler">dschepler</who>
            <bug_when>2012-09-10 17:59:14 +0000</bug_when>
            <thetext>(In reply to comment #9)
&gt; Please try hjl/pr14562/2.16 branch.

As I already commented on the x32 list, for me this fixes among other things: gij running ecj, and the GraphicsMagick, perl and pixman testsuites.</thetext>
          </long_desc>
          <long_desc isprivate="0">
            <commentid>57576</commentid>
            <who name="H.J. Lu">hjl.tools</who>
            <bug_when>2012-09-25 00:20:53 +0000</bug_when>
            <thetext>Fixed in 2.17 by

http://sourceware.org/git/?p=glibc.git;a=commit;h=ced6f16ee919d12725840d43d007f1cfd67118df</thetext>
          </long_desc>
          <long_desc isprivate="0">
            <commentid>57624</commentid>
            <who name="H.J. Lu">hjl.tools</who>
            <bug_when>2012-09-26 18:33:18 +0000</bug_when>
            <thetext>Fixed in 2.16.1 by

http://sourceware.org/git/?p=glibc.git;a=commit;h=bbe53ed2c311b7281837b6f3f24ddeb8f3d65697</thetext>
          </long_desc>
      
      

    </bug>

</bugzilla>