Hi,

I'm using offlineimap 5.99.4 with Fink under OSX, and whenever a large message
needs to be downloaded it dies with a MemoryError traceback.

After doing a bit of research I discovered this page which suggested that
Darwin's realloc was at fault. Apparently it doesn't always shrink memory.
http://bugs.python.org/issue1092502

I've got a somewhat nasty patch for Python2.5 in fink that implements
hacked_realloc that fixes the problem. I've been using it for over 6 months
with no problems. The patched Python has caused me no problems with any other
apps and I use it regularly.

Not sure what the best way for this to go into fink would be, or even if it
should be. For anybody else who comes across the issue this patch should help.


Here are the steps to use the patch
 * Copy python25.info and .patch from /sw/fink/dists/unstable/languages
   into /sw/fink/dists/local/main/finkinfo
 * Append the attached patch to python25.patch
 * Update the Patchfile-MD5 in python25.info
 * Add .1 to the version in python25.info

Hope this is useful to somebody :)

---

James

diff -ur a/Python-2.5.1/Objects/obmalloc.c b/Python-2.5.1/Objects/obmalloc.c
--- a/Python-2.5.1/Objects/obmalloc.c   2006-10-29 08:39:31.000000000 +1100
+++ b/Python-2.5.1/Objects/obmalloc.c   2007-09-14 02:00:11.000000000 +1000
@@ -1114,6 +1114,34 @@
        free(p);
 }
 
+
+#ifdef __APPLE__
+/* hacked_realloc. This is a workaround for the realloc on OSX, which never
+ * shrinks the amount of allocated memory.
+ */
+#include <malloc/malloc.h>
+// Why can't I find this in a header anywhere?
+size_t malloc_good_size(size_t size);
+static inline void *
+hacked_realloc(void *p, size_t nbytes)
+{
+       nbytes = nbytes ? nbytes : 1;
+       if(malloc_size(p) > malloc_good_size(nbytes)) {
+               void * p2 = malloc(nbytes);
+               if(!p2) {
+                       return NULL;
+               }
+               if(p) {
+                       memcpy(p2, p, nbytes);
+                       free(p);
+               }
+               return p2;
+       }
+       return realloc(p, nbytes);
+}
+#endif // __APPLE__
+
+
 /* realloc.  If p is NULL, this acts like malloc(nbytes).  Else if nbytes==0,
  * then as the Python docs promise, we do not treat this like free(p), and
  * return a non-NULL result.
@@ -1168,14 +1196,22 @@
         * at p.  Instead we punt:  let C continue to manage this block.
          */
        if (nbytes)
+#ifdef __APPLE__
+               return hacked_realloc(p, nbytes);
+#else
                return realloc(p, nbytes);
+#endif
        /* C doesn't define the result of realloc(p, 0) (it may or may not
         * return NULL then), but Python's docs promise that nbytes==0 never
         * returns NULL.  We don't pass 0 to realloc(), to avoid that endcase
         * to begin with.  Even then, we can't be sure that realloc() won't
         * return NULL.
         */
+#ifdef __APPLE__
+       bp = hacked_realloc(p, 1);
+#else
        bp = realloc(p, 1);
+#endif
        return bp ? bp : p;
 }
 
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Fink-devel mailing list
Fink-devel@lists.sourceforge.net
http://news.gmane.org/gmane.os.apple.fink.devel

Reply via email to