[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: gEDA-user: PCB head fails with ***MEMORY-ERROR***




I think I've got it. The following patch (also posted on
Launchpad) fixes the bug on my system. I am posting it here
for review and testing.

There are two leaks I fixed:

  1. ENDALL_LOOP did not free memory. Now it does.

  2. If you return early from a list using the macro.h macros,
     list memory is not freed. I added an END_LOOP_EARLY macro
     to handle this. However, there are a few problems with
     this approach:

   a. It isn't obvious, especially to new devs, that you
      need to prefix all early returns with this macro.
      Plus, it's ugly.

   b. It only works on 1-level-deep loops. Supporting double-
      or higher nesting will be very difficult with the current
      macro setup.

I dunno what should be done about this. For now, this works
and also drops pcb's increasing memory use for normal work.
(Maybe there are still leaks; I just haven't noticed yet.)
Anyway, this patch will work for now.     



diff --git a/src/macro.h b/src/macro.h
index b61f673..efcec67 100644
--- a/src/macro.h
+++ b/src/macro.h
@@ -175,6 +175,8 @@ extern int mem_any_set (unsigned char *, int);
     g_list_free (__copy);                                           \
   } while (0)
 
+#define END_LOOP_EARLY	g_list_free (__copy);
+
 #define STYLE_LOOP(top)  do {                                       \
         GList *__copy = NULL; /* DUMMY */                           \
         Cardinal n;                                                 \
@@ -328,7 +330,11 @@ extern int mem_any_set (unsigned char *, int);
 	{						\
 		point = &(polygon)->Points[n]
 
-#define ENDALL_LOOP }} while (0);  }} while (0)
+#define ENDALL_LOOP } 		\
+      g_list_free (__copy);	\
+    } while (0); }		\
+    g_list_free (__copy);	\
+  } while (0)
 
 #define	ALLPIN_LOOP(top)	\
         ELEMENT_LOOP(top); \
@@ -340,6 +346,7 @@ extern int mem_any_set (unsigned char *, int);
 
 #define	ALLLINE_LOOP(top) do	{		\
 	Cardinal		l;			\
+	GList *__copy = NULL; /* DUMMY */		\
 	LayerTypePtr	layer = (top)->Layer;		\
 	for (l = 0; l < max_copper_layer + 2; l++, layer++)	\
 	{ \
@@ -347,6 +354,7 @@ extern int mem_any_set (unsigned char *, int);
 
 #define ALLARC_LOOP(top) do {		\
 	Cardinal		l;			\
+	GList *__copy = NULL; /* DUMMY */		\
 	LayerTypePtr	layer = (top)->Layer;		\
 	for (l =0; l < max_copper_layer + 2; l++, layer++)		\
 	{ \
@@ -354,6 +362,7 @@ extern int mem_any_set (unsigned char *, int);
 
 #define	ALLPOLYGON_LOOP(top)	do {		\
 	Cardinal		l;			\
+	GList *__copy = NULL; /* DUMMY */		\
 	LayerTypePtr	layer = (top)->Layer;		\
 	for (l = 0; l < max_copper_layer + 2; l++, layer++)	\
 	{ \
@@ -361,6 +370,7 @@ extern int mem_any_set (unsigned char *, int);
 
 #define	COPPERLINE_LOOP(top) do	{		\
 	Cardinal		l;			\
+	GList *__copy = NULL; /* DUMMY */		\
 	LayerTypePtr	layer = (top)->Layer;		\
 	for (l = 0; l < max_copper_layer; l++, layer++)	\
 	{ \
@@ -368,6 +378,7 @@ extern int mem_any_set (unsigned char *, int);
 
 #define COPPERARC_LOOP(top) do	{		\
 	Cardinal		l;			\
+	GList *__copy = NULL; /* DUMMY */		\
 	LayerTypePtr	layer = (top)->Layer;		\
 	for (l =0; l < max_copper_layer; l++, layer++)		\
 	{ \
@@ -375,6 +386,7 @@ extern int mem_any_set (unsigned char *, int);
 
 #define	COPPERPOLYGON_LOOP(top) do	{		\
 	Cardinal		l;			\
+	GList *__copy = NULL; /* DUMMY */		\
 	LayerTypePtr	layer = (top)->Layer;		\
 	for (l = 0; l < max_copper_layer; l++, layer++)	\
 	{ \
@@ -382,6 +394,7 @@ extern int mem_any_set (unsigned char *, int);
 
 #define	SILKLINE_LOOP(top) do	{		\
 	Cardinal		l;			\
+	GList *__copy = NULL; /* DUMMY */		\
 	LayerTypePtr	layer = (top)->Layer;		\
 	layer += max_copper_layer;			\
 	for (l = 0; l < 2; l++, layer++)		\
@@ -390,6 +403,7 @@ extern int mem_any_set (unsigned char *, int);
 
 #define SILKARC_LOOP(top) do	{		\
 	Cardinal		l;			\
+	GList *__copy = NULL; /* DUMMY */		\
 	LayerTypePtr	layer = (top)->Layer;		\
 	layer += max_copper_layer;			\
 	for (l = 0; l < 2; l++, layer++)		\
@@ -398,6 +412,7 @@ extern int mem_any_set (unsigned char *, int);
 
 #define	SILKPOLYGON_LOOP(top) do	{		\
 	Cardinal		l;			\
+	GList *__copy = NULL; /* DUMMY */		\
 	LayerTypePtr	layer = (top)->Layer;		\
 	layer += max_copper_layer;			\
 	for (l = 0; l < 2; l++, layer++)		\
@@ -406,6 +421,7 @@ extern int mem_any_set (unsigned char *, int);
 
 #define	ALLTEXT_LOOP(top)	do {		\
 	Cardinal		l;			\
+	GList *__copy = NULL; /* DUMMY */		\
 	LayerTypePtr	layer = (top)->Layer;		\
 	for (l = 0; l < max_copper_layer + 2; l++, layer++)	\
 	{ \
@@ -413,6 +429,7 @@ extern int mem_any_set (unsigned char *, int);
 
 #define	VISIBLELINE_LOOP(top) do	{		\
 	Cardinal		l;			\
+	GList *__copy = NULL; /* DUMMY */		\
 	LayerTypePtr	layer = (top)->Layer;		\
 	for (l = 0; l < max_copper_layer + 2; l++, layer++)	\
 	{ \
@@ -421,6 +438,7 @@ extern int mem_any_set (unsigned char *, int);
 
 #define	VISIBLEARC_LOOP(top) do	{		\
 	Cardinal		l;			\
+	GList *__copy = NULL; /* DUMMY */		\
 	LayerTypePtr	layer = (top)->Layer;		\
 	for (l = 0; l < max_copper_layer + 2; l++, layer++)	\
 	{ \
@@ -429,6 +447,7 @@ extern int mem_any_set (unsigned char *, int);
 
 #define	VISIBLETEXT_LOOP(board) do	{		\
 	Cardinal		l;			\
+	GList *__copy = NULL; /* DUMMY */		\
 	LayerTypePtr	layer = (board)->Data->Layer;		\
 	for (l = 0; l < max_copper_layer + 2; l++, layer++)	\
 	{ \
@@ -437,6 +456,7 @@ extern int mem_any_set (unsigned char *, int);
 
 #define	VISIBLEPOLYGON_LOOP(top) do	{	\
 	Cardinal		l;			\
+	GList *__copy = NULL; /* DUMMY */		\
 	LayerTypePtr	layer = (top)->Layer;		\
 	for (l = 0; l < max_copper_layer + 2; l++, layer++)	\
 	{ \
diff --git a/src/search.c b/src/search.c
index 30fe883..b50f3cb 100644
--- a/src/search.c
+++ b/src/search.c
@@ -1383,6 +1383,7 @@ SearchObjectByID (DataTypePtr Base,
 	  {
 	    *Result1 = (void *) layer;
 	    *Result2 = *Result3 = (void *) line;
+	    END_LOOP_EARLY;
 	    return (LINE_TYPE);
 	  }
 	if (line->Point1.ID == ID)
@@ -1390,6 +1391,7 @@ SearchObjectByID (DataTypePtr Base,
 	    *Result1 = (void *) layer;
 	    *Result2 = (void *) line;
 	    *Result3 = (void *) &line->Point1;
+	    END_LOOP_EARLY;
 	    return (LINEPOINT_TYPE);
 	  }
 	if (line->Point2.ID == ID)
@@ -1397,6 +1399,7 @@ SearchObjectByID (DataTypePtr Base,
 	    *Result1 = (void *) layer;
 	    *Result2 = (void *) line;
 	    *Result3 = (void *) &line->Point2;
+	    END_LOOP_EARLY;
 	    return (LINEPOINT_TYPE);
 	  }
       }
@@ -1410,6 +1413,7 @@ SearchObjectByID (DataTypePtr Base,
 	  {
 	    *Result1 = (void *) layer;
 	    *Result2 = *Result3 = (void *) arc;
+	    END_LOOP_EARLY;
 	    return (ARC_TYPE);
 	  }
       }
@@ -1424,6 +1428,7 @@ SearchObjectByID (DataTypePtr Base,
 	  {
 	    *Result1 = (void *) layer;
 	    *Result2 = *Result3 = (void *) text;
+	    END_LOOP_EARLY;
 	    return (TEXT_TYPE);
 	  }
       }
@@ -1438,6 +1443,7 @@ SearchObjectByID (DataTypePtr Base,
 	  {
 	    *Result1 = (void *) layer;
 	    *Result2 = *Result3 = (void *) polygon;
+	    END_LOOP_EARLY;
 	    return (POLYGON_TYPE);
 	  }
 	if (type == POLYGONPOINT_TYPE)
@@ -1448,6 +1454,7 @@ SearchObjectByID (DataTypePtr Base,
 	      *Result1 = (void *) layer;
 	      *Result2 = (void *) polygon;
 	      *Result3 = (void *) point;
+	      END_LOOP_EARLY;
 	      return (POLYGONPOINT_TYPE);
 	    }
 	}
@@ -1462,6 +1469,7 @@ SearchObjectByID (DataTypePtr Base,
 	if (via->ID == ID)
 	  {
 	    *Result1 = *Result2 = *Result3 = (void *) via;
+	    END_LOOP_EARLY;
 	    return (VIA_TYPE);
 	  }
       }
@@ -1475,6 +1483,7 @@ SearchObjectByID (DataTypePtr Base,
 	if (line->ID == ID)
 	  {
 	    *Result1 = *Result2 = *Result3 = (void *) line;
+	    END_LOOP_EARLY;
 	    return (RATLINE_TYPE);
 	  }
 	if (line->Point1.ID == ID)
@@ -1482,6 +1491,7 @@ SearchObjectByID (DataTypePtr Base,
 	    *Result1 = (void *) NULL;
 	    *Result2 = (void *) line;
 	    *Result3 = (void *) &line->Point1;
+	    END_LOOP_EARLY;
 	    return (LINEPOINT_TYPE);
 	  }
 	if (line->Point2.ID == ID)
@@ -1489,6 +1499,7 @@ SearchObjectByID (DataTypePtr Base,
 	    *Result1 = (void *) NULL;
 	    *Result2 = (void *) line;
 	    *Result3 = (void *) &line->Point2;
+	    END_LOOP_EARLY;
 	    return (LINEPOINT_TYPE);
 	  }
       }
@@ -1504,6 +1515,7 @@ SearchObjectByID (DataTypePtr Base,
     if (element->ID == ID)
       {
 	*Result1 = *Result2 = *Result3 = (void *) element;
+        END_LOOP_EARLY;
 	return (ELEMENT_TYPE);
       }
     if (type == ELEMENTLINE_TYPE)
@@ -1513,6 +1525,7 @@ SearchObjectByID (DataTypePtr Base,
 	{
 	  *Result1 = (void *) element;
 	  *Result2 = *Result3 = (void *) line;
+          END_LOOP_EARLY;
 	  return (ELEMENTLINE_TYPE);
 	}
     }
@@ -1524,6 +1537,7 @@ SearchObjectByID (DataTypePtr Base,
 	{
 	  *Result1 = (void *) element;
 	  *Result2 = *Result3 = (void *) arc;
+          END_LOOP_EARLY;
 	  return (ELEMENTARC_TYPE);
 	}
     }
@@ -1535,6 +1549,7 @@ SearchObjectByID (DataTypePtr Base,
 	{
 	  *Result1 = (void *) element;
 	  *Result2 = *Result3 = (void *) text;
+          END_LOOP_EARLY;
 	  return (ELEMENTNAME_TYPE);
 	}
     }
@@ -1546,6 +1561,7 @@ SearchObjectByID (DataTypePtr Base,
 	{
 	  *Result1 = (void *) element;
 	  *Result2 = *Result3 = (void *) pin;
+          END_LOOP_EARLY;
 	  return (PIN_TYPE);
 	}
     }
@@ -1557,6 +1573,7 @@ SearchObjectByID (DataTypePtr Base,
 	{
 	  *Result1 = (void *) element;
 	  *Result2 = *Result3 = (void *) pad;
+          END_LOOP_EARLY;
 	  return (PAD_TYPE);
 	}
     }
@@ -1583,6 +1600,7 @@ SearchElementByName (DataTypePtr Base, char *Name)
 	NSTRCMP (element->Name[1].TextString, Name) == 0)
       {
 	result = element;
+	END_LOOP_EARLY;
 	return (result);
       }
   }



_______________________________________________
geda-user mailing list
geda-user@xxxxxxxxxxxxxx
http://www.seul.org/cgi-bin/mailman/listinfo/geda-user