bug-gnu-utils
[Top][All Lists]
Advanced

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

Re: Memory allocation problem with latest gawk - new testcase


From: Aharon Robbins
Subject: Re: Memory allocation problem with latest gawk - new testcase
Date: Thu, 3 Apr 2003 18:09:41 +0300

Here is a temporary fix that solves your test case and that gets through
the test suite.  The main change was the ifdef-ing out of the calls to
grow_iop_buffer().  The other changes fix a different problem, but you
may as well have all the fixes.

Thanks for reporting the problem, and apologies for being a little
dense about it at the beginning.  Stepan, thanks for the analysis.

Arnold
-------------------------
--- ../gawk-3.1.2/io.c  2003-02-25 12:32:30.000000000 +0200
+++ io.c        2003-04-03 17:14:56.000000000 +0300
@@ -2487,11 +2487,13 @@
 
                                 /* <reset pointers>=                           
                             */
                                 bp = iop->dataend;
+#if 0
                         } else {
                                 /* <save position, grow buffer>=               
                             */
                                 iop->scanoff = bp - iop->off;
                                 grow_iop_buffer(iop);
                                 bp = iop->off + iop->scanoff;
+#endif
                         }
                 }
 
@@ -2506,11 +2508,16 @@
                         /* Use read to put more data into the buffer. If we've 
read                 */
                         /* as many characters as in the file, don't try to 
read more.               */
                         /*                                                     
                     */
+                        /* Well, not quite.  Linux files such as 
/proc/filesystems show             */
+                        /* up to stat() as though they're of size zero, but in 
fact they            */
+                        /* have data in them.  IMHO this is a Linux bug.       
                     */
+                        /*                                                     
                     */
                         /*                                                     
                     */
                         /* <put more data into the buffer>=                    
                     */
                         if ((iop->flag & IOP_IS_INTERNAL) != 0) {
                                 iop->flag |= IOP_AT_EOF;
-                        } else if (S_ISREG(iop->sbuf.st_mode) && iop->total >= 
iop->sbuf.st_size)
+                        } else if (S_ISREG(iop->sbuf.st_mode) && 
iop->sbuf.st_size > 0
+                                   && iop->total >= iop->sbuf.st_size)
                                 iop->flag |= IOP_AT_EOF;
                         else {
 #define min(x, y) (x < y ? x : y)
@@ -2549,7 +2556,8 @@
                                 else {
                                         iop->dataend += iop->count;
                                         iop->total += iop->count;
-                                        if (S_ISREG(iop->sbuf.st_mode) && 
iop->total >= iop->sbuf.st_size)
+                                        if (S_ISREG(iop->sbuf.st_mode) && 
iop->sbuf.st_size > 0
+                                            && iop->total >= iop->sbuf.st_size)
                                                 iop->flag |= IOP_AT_EOF;
                                         /* reset the sentinel */
                                         /* <set sentinel>=                     
                                     */
@@ -2729,11 +2737,13 @@
 
                                 /* <reset pointers>=                           
                             */
                                 bp = iop->dataend;
+#if 0
                         } else {
                                 /* <save position, grow buffer>=               
                             */
                                 iop->scanoff = bp - iop->off;
                                 grow_iop_buffer(iop);
                                 bp = iop->off + iop->scanoff;
+#endif
                         }
                 }
 
@@ -2748,11 +2758,16 @@
                         /* Use read to put more data into the buffer. If we've 
read                 */
                         /* as many characters as in the file, don't try to 
read more.               */
                         /*                                                     
                     */
+                        /* Well, not quite.  Linux files such as 
/proc/filesystems show             */
+                        /* up to stat() as though they're of size zero, but in 
fact they            */
+                        /* have data in them.  IMHO this is a Linux bug.       
                     */
+                        /*                                                     
                     */
                         /*                                                     
                     */
                         /* <put more data into the buffer>=                    
                     */
                         if ((iop->flag & IOP_IS_INTERNAL) != 0) {
                                 iop->flag |= IOP_AT_EOF;
-                        } else if (S_ISREG(iop->sbuf.st_mode) && iop->total >= 
iop->sbuf.st_size)
+                        } else if (S_ISREG(iop->sbuf.st_mode) && 
iop->sbuf.st_size > 0
+                                   && iop->total >= iop->sbuf.st_size)
                                 iop->flag |= IOP_AT_EOF;
                         else {
 #define min(x, y) (x < y ? x : y)
@@ -2791,7 +2806,8 @@
                                 else {
                                         iop->dataend += iop->count;
                                         iop->total += iop->count;
-                                        if (S_ISREG(iop->sbuf.st_mode) && 
iop->total >= iop->sbuf.st_size)
+                                        if (S_ISREG(iop->sbuf.st_mode) && 
iop->sbuf.st_size > 0
+                                            && iop->total >= iop->sbuf.st_size)
                                                 iop->flag |= IOP_AT_EOF;
                                         /* reset the sentinel */
                                         /* <set sentinel>=                     
                                     */
@@ -2993,11 +3009,13 @@
 
                                 /* <reset pointers>=                           
                             */
                                 bp = iop->dataend;
+#if 0
                         } else {
                                 /* <save position, grow buffer>=               
                             */
                                 iop->scanoff = bp - iop->off;
                                 grow_iop_buffer(iop);
                                 bp = iop->off + iop->scanoff;
+#endif
                         }
                 }
 
@@ -3012,11 +3030,16 @@
                         /* Use read to put more data into the buffer. If we've 
read                 */
                         /* as many characters as in the file, don't try to 
read more.               */
                         /*                                                     
                     */
+                        /* Well, not quite.  Linux files such as 
/proc/filesystems show             */
+                        /* up to stat() as though they're of size zero, but in 
fact they            */
+                        /* have data in them.  IMHO this is a Linux bug.       
                     */
+                        /*                                                     
                     */
                         /*                                                     
                     */
                         /* <put more data into the buffer>=                    
                     */
                         if ((iop->flag & IOP_IS_INTERNAL) != 0) {
                                 iop->flag |= IOP_AT_EOF;
-                        } else if (S_ISREG(iop->sbuf.st_mode) && iop->total >= 
iop->sbuf.st_size)
+                        } else if (S_ISREG(iop->sbuf.st_mode) && 
iop->sbuf.st_size > 0
+                                   && iop->total >= iop->sbuf.st_size)
                                 iop->flag |= IOP_AT_EOF;
                         else {
 #define min(x, y) (x < y ? x : y)
@@ -3055,7 +3078,8 @@
                                 else {
                                         iop->dataend += iop->count;
                                         iop->total += iop->count;
-                                        if (S_ISREG(iop->sbuf.st_mode) && 
iop->total >= iop->sbuf.st_size)
+                                        if (S_ISREG(iop->sbuf.st_mode) && 
iop->sbuf.st_size > 0
+                                            && iop->total >= iop->sbuf.st_size)
                                                 iop->flag |= IOP_AT_EOF;
                                         /* reset the sentinel */
                                         /* <set sentinel>=                     
                                     */




reply via email to

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