avr-libc-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[avr-libc-commit] [2127] Submitted by Aleksandar Kanchev:


From: Joerg Wunsch
Subject: [avr-libc-commit] [2127] Submitted by Aleksandar Kanchev:
Date: Mon, 07 Jun 2010 14:49:37 +0000

Revision: 2127
          http://svn.sv.gnu.org/viewvc/?view=rev&root=avr-libc&revision=2127
Author:   joerg_wunsch
Date:     2010-06-07 14:49:37 +0000 (Mon, 07 Jun 2010)
Log Message:
-----------
Submitted by Aleksandar Kanchev:
bug #27242: realloc: serious error when size shrinks
* stdlib/reallo.c: Change freelist calculation.
* tests/simulate/regression/bug-27242.c: New file.

Ticket Links:
:-----------
    http://savannah.gnu.org/bugs/?27242

Modified Paths:
--------------
    trunk/avr-libc/ChangeLog
    trunk/avr-libc/NEWS
    trunk/avr-libc/libc/stdlib/realloc.c

Added Paths:
-----------
    trunk/avr-libc/tests/simulate/regression/bug-27242.c

Modified: trunk/avr-libc/ChangeLog
===================================================================
--- trunk/avr-libc/ChangeLog    2010-06-07 14:17:06 UTC (rev 2126)
+++ trunk/avr-libc/ChangeLog    2010-06-07 14:49:37 UTC (rev 2127)
@@ -1,5 +1,12 @@
 2010-06-07  Joerg Wunsch <address@hidden>
 
+       Submitted by Aleksandar Kanchev:
+       bug #27242: realloc: serious error when size shrinks
+       * stdlib/reallo.c: Change freelist calculation.
+       * tests/simulate/regression/bug-27242.c: New file.
+
+2010-06-07  Joerg Wunsch <address@hidden>
+
        * tests/simulate/stdlib/malloc-4.c: New file.
 
 2010-06-04  Joerg Wunsch <address@hidden>

Modified: trunk/avr-libc/NEWS
===================================================================
--- trunk/avr-libc/NEWS 2010-06-07 14:17:06 UTC (rev 2126)
+++ trunk/avr-libc/NEWS 2010-06-07 14:49:37 UTC (rev 2127)
@@ -104,6 +104,7 @@
   [#26876] include io.h into fuse.h
   [#27201] _WORDREGISTER in xmega headers does not work in C99 mode
   [#27235] malloc: Several things go wrong (part 1)
+  [#27242] realloc: serious error when size shrinks
   [#27367] RAMSTART missing in elder device header files
   [#27434] Arguments of macros must be protected in parentheses
   [#28575] Minor bug in iousb162.h - missing FUSE_ prefixes

Modified: trunk/avr-libc/libc/stdlib/realloc.c
===================================================================
--- trunk/avr-libc/libc/stdlib/realloc.c        2010-06-07 14:17:06 UTC (rev 
2126)
+++ trunk/avr-libc/libc/stdlib/realloc.c        2010-06-07 14:49:37 UTC (rev 
2127)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2004 Joerg Wunsch
+/* Copyright (c) 2004, 2010 Joerg Wunsch
    All rights reserved.
 
    Redistribution and use in source and binary forms, with or without
@@ -60,7 +60,6 @@
        if (cp < cp1)
                /* Pointer wrapped across top of RAM, fail. */
                return 0;
-       fp2 = (struct __freelist *)(cp - sizeof(size_t));
 
        /*
         * See whether we are growing or shrinking.  When shrinking,
@@ -75,6 +74,7 @@
                if (fp1->sz <= sizeof(struct __freelist) ||
                    len > fp1->sz - sizeof(struct __freelist))
                        return ptr;
+               fp2 = (struct __freelist *)cp;
                fp2->sz = fp1->sz - len - sizeof(size_t);
                fp1->sz = len;
                free(&(fp2->nx));
@@ -87,30 +87,28 @@
         */
        incr = len - fp1->sz;
        cp = (char *)ptr + fp1->sz;
+       fp2 = (struct __freelist *)cp;
        for (s = 0, ofp3 = 0, fp3 = __flp;
             fp3;
             ofp3 = fp3, fp3 = fp3->nx) {
-               if (fp3 == fp2 && fp3->sz >= incr) {
+               if (fp3 == fp2 && fp3->sz + sizeof(size_t) >= incr) {
                        /* found something that fits */
-                       if (incr <= fp3->sz + sizeof(size_t)) {
+                       if (fp3->sz + sizeof(size_t) - incr > sizeof(struct 
__freelist)) {
+                               /* split off a new freelist entry */
+                               cp = (char *)ptr + len;
+                               fp2 = (struct __freelist *)cp;
+                               fp2->nx = fp3->nx;
+                               fp2->sz = fp3->sz - incr;
+                               fp1->sz = len;
+                       } else {
                                /* it just fits, so use it entirely */
                                fp1->sz += fp3->sz + sizeof(size_t);
-                               if (ofp3)
-                                       ofp3->nx = fp3->nx;
-                               else
-                                       __flp = fp3->nx;
-                               return ptr;
+                               fp2 = fp3->nx;
                        }
-                       /* split off a new freelist entry */
-                       cp = (char *)ptr + len;
-                       fp2 = (struct __freelist *)(cp - sizeof(size_t));
-                       fp2->nx = fp3->nx;
-                       fp2->sz = fp3->sz - incr - sizeof(size_t);
                        if (ofp3)
                                ofp3->nx = fp2;
                        else
                                __flp = fp2;
-                       fp1->sz = len;
                        return ptr;
                }
                /*

Added: trunk/avr-libc/tests/simulate/regression/bug-27242.c
===================================================================
--- trunk/avr-libc/tests/simulate/regression/bug-27242.c                        
        (rev 0)
+++ trunk/avr-libc/tests/simulate/regression/bug-27242.c        2010-06-07 
14:49:37 UTC (rev 2127)
@@ -0,0 +1,101 @@
+/* Copyright (c) 2009 Aleksandar Kanchev
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+
+   * Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+
+   * Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in
+     the documentation and/or other materials provided with the
+     distribution.
+
+   * Neither the name of the copyright holders nor the names of
+     contributors may be used to endorse or promote products derived
+     from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/* $Id$ */
+
+#include <stdlib.h>
+
+#include "../../libc/stdlib/stdlib_private.h"
+
+
+/* Test code from bug #27242 (and #25723) */
+int main(void)
+{
+       char *p, *p1;
+
+       p = malloc(16);
+       if (!p)
+               return 1;
+
+       /* releasing 6 bytes creates a new free chunk */
+       p1 = realloc(p, 10);
+       if (p != p1)
+               return 2;
+
+       /*
+        * The patch for bug #25723 introduces a regression to realloc()
+        * when called to shrink a memory chunk. We simply verify if
+        * the new free chunk starts immediately after the last allocated
+        * chunk.
+        */
+       p = p1 + 10;
+       if ((char*)__flp != p)
+               return 3;
+
+       /* use the last free chunk */
+       p1 = malloc(4);
+       if (!p1)
+               return 4;
+
+       /* should be empty */
+       if (__flp)
+               return 5;
+
+       p = malloc(10);
+       if (!p)
+               return 6;
+
+       /* force creation of a new minimal free chunk (sz = 3) */
+       p1 = realloc(p, 5);
+       if (p != p1)
+               return 7;
+
+       p = p1 + 5;
+       if ((char*)__flp != p)
+               return 8;
+
+       /* merge with the free chunk (incr = 4 > sz = 3) */
+       p = realloc(p1, 9);
+       if (p != p1)
+               return 9;
+
+       /* chunk size should be 10 */
+       p -= sizeof(size_t);
+       if (*(size_t *)p != 10)
+               return 10;
+
+       /* should be empty */
+       if (__flp)
+               return 11;
+
+       return 0;
+}
+


Property changes on: trunk/avr-libc/tests/simulate/regression/bug-27242.c
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Author Id Date
Added: svn:eol-style
   + native




reply via email to

[Prev in Thread] Current Thread [Next in Thread]