[pypy-svn] r77989 - pypy/branch/leak-finder/pypy/translator/c/src

arigo at codespeak.net arigo at codespeak.net
Fri Oct 15 15:50:14 CEST 2010


Author: arigo
Date: Fri Oct 15 15:50:13 2010
New Revision: 77989

Added:
   pypy/branch/leak-finder/pypy/translator/c/src/debug_alloc.h
Modified:
   pypy/branch/leak-finder/pypy/translator/c/src/g_include.h
   pypy/branch/leak-finder/pypy/translator/c/src/main.h
Log:
In RPY_ASSERT mode, print a warning at the end of running a translated
program if there are malloc()s without a corresponding free().  If you
get more than a few ones, you have a leak.


Added: pypy/branch/leak-finder/pypy/translator/c/src/debug_alloc.h
==============================================================================
--- (empty file)
+++ pypy/branch/leak-finder/pypy/translator/c/src/debug_alloc.h	Fri Oct 15 15:50:13 2010
@@ -0,0 +1,81 @@
+/**************************************************************/
+ /***  tracking raw mallocs and frees for debugging          ***/
+
+#ifndef RPY_ASSERT
+
+#  define OP_TRACK_ALLOC_START(addr, r)   /* nothing */
+#  define OP_TRACK_ALLOC_STOP(addr, r)    /* nothing */
+
+#else   /* ifdef RPY_ASSERT */
+
+#  define OP_TRACK_ALLOC_START(addr, r)  pypy_debug_alloc_start(addr, \
+                                                                __FUNCTION__)
+#  define OP_TRACK_ALLOC_STOP(addr, r)   pypy_debug_alloc_stop(addr)
+
+void pypy_debug_alloc_start(void*, const char*);
+void pypy_debug_alloc_stop(void*);
+void pypy_debug_alloc_results(void);
+
+/************************************************************/
+
+
+#ifndef PYPY_NOT_MAIN_FILE
+
+struct pypy_debug_alloc_s {
+  struct pypy_debug_alloc_s *next;
+  void *addr;
+  const char *funcname;
+};
+
+static struct pypy_debug_alloc_s *pypy_debug_alloc_list = NULL;
+
+void pypy_debug_alloc_start(void *addr, const char *funcname)
+{
+  struct pypy_debug_alloc_s *p = malloc(sizeof(struct pypy_debug_alloc_s));
+  RPyAssert(p, "out of memory");
+  p->next = pypy_debug_alloc_list;
+  p->addr = addr;
+  p->funcname = funcname;
+  pypy_debug_alloc_list = p;
+}
+
+void pypy_debug_alloc_stop(void *addr)
+{
+  struct pypy_debug_alloc_s **p;
+  for (p = &pypy_debug_alloc_list; *p; p = &((*p)->next))
+    if ((*p)->addr == addr)
+      {
+        struct pypy_debug_alloc_s *dying;
+        dying = *p;
+        *p = dying->next;
+        free(dying);
+        return;
+      }
+  RPyAssert(0, "free() of a never-malloc()ed object");
+}
+
+void pypy_debug_alloc_results(void)
+{
+  long count = 0;
+  struct pypy_debug_alloc_s *p;
+  for (p = pypy_debug_alloc_list; p; p = p->next)
+    count++;
+  if (count > 0)
+    {
+      fprintf(stderr, "debug_alloc.h: %ld mallocs left", count);
+      char *env = getenv("PYPY_ALLOC");
+      if (env && *env)
+        {
+          fprintf(stderr, " (most recent first):\n");
+          for (p = pypy_debug_alloc_list; p; p = p->next)
+            fprintf(stderr, "    %p  %s\n", p->addr, p->funcname);
+        }
+      else
+        fprintf(stderr, " (use PYPY_ALLOC=1 to see the list)\n");
+    }
+}
+
+#endif
+
+
+#endif  /* RPY_ASSERT */

Modified: pypy/branch/leak-finder/pypy/translator/c/src/g_include.h
==============================================================================
--- pypy/branch/leak-finder/pypy/translator/c/src/g_include.h	(original)
+++ pypy/branch/leak-finder/pypy/translator/c/src/g_include.h	Fri Oct 15 15:50:13 2010
@@ -53,6 +53,7 @@
 #  include "src/rtyper.h"
 #  include "src/debug_print.h"
 #  include "src/debug_traceback.h"
+#  include "src/debug_alloc.h"
 #ifndef AVR
 #  include "src/ll_os.h"
 #  include "src/ll_strtod.h"

Modified: pypy/branch/leak-finder/pypy/translator/c/src/main.h
==============================================================================
--- pypy/branch/leak-finder/pypy/translator/c/src/main.h	(original)
+++ pypy/branch/leak-finder/pypy/translator/c/src/main.h	Fri Oct 15 15:50:13 2010
@@ -53,10 +53,16 @@
     }
 
     exitcode = STANDALONE_ENTRY_POINT(list);
+
+#ifdef RPY_ASSERT
+    pypy_debug_alloc_results();
+#endif
+
     if (RPyExceptionOccurred()) {
         /* print the RPython traceback */
         pypy_debug_catch_fatal_exception();
     }
+
     return exitcode;
 
  memory_out:



More information about the Pypy-commit mailing list