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

gEDA-cvs: pcb.git: branch: master updated (b996bb2e352d390a45db60580b0816b233950fe7)



The branch, master has been updated
       via  b996bb2e352d390a45db60580b0816b233950fe7 (commit)
      from  5c0e88f2d44c4a22b6afa770750f2a599b048e2b (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


=========
 Summary
=========

 src/Makefile.am   |    2 +
 src/free_atexit.c |   91 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/free_atexit.h |   30 +++++++++++++++++
 src/main.c        |    8 +++++
 4 files changed, 131 insertions(+), 0 deletions(-)
 create mode 100644 src/free_atexit.c
 create mode 100644 src/free_atexit.h


=================
 Commit Messages
=================

commit b996bb2e352d390a45db60580b0816b233950fe7
Author: Tibor Palinkas <geda@xxxxxxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Add leaky_{malloc,realloc} functions for deliberate non-free'd allocations
    
    These are to be used for local allocations made and cached for
    the lifetime of the program (never free'd). Typically, these are stored
    in a static char * variable (or similar) within a function.
    
    The leaky_*() functions store the addresses of all memory they allocate,
    and for debugging builds, free it upon exit of the program, thus allowing
    leak detectors such as valgrind to ignore our deliberate "leaks".
    
    The memory returned by leaky_*() must not be free'd.
    
    Build system and PCB integration, and leaky_atexit.c reindenting by
    Peter Clifton <pcjc2@xxxxxxxxx>

:100644 100644 a0f1c50... e287ae7... M	src/Makefile.am
:000000 100644 0000000... dc11f12... A	src/free_atexit.c
:000000 100644 0000000... 3b142b6... A	src/free_atexit.h
:100644 100644 462285d... 735fde7... M	src/main.c

=========
 Changes
=========

commit b996bb2e352d390a45db60580b0816b233950fe7
Author: Tibor Palinkas <geda@xxxxxxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Add leaky_{malloc,realloc} functions for deliberate non-free'd allocations
    
    These are to be used for local allocations made and cached for
    the lifetime of the program (never free'd). Typically, these are stored
    in a static char * variable (or similar) within a function.
    
    The leaky_*() functions store the addresses of all memory they allocate,
    and for debugging builds, free it upon exit of the program, thus allowing
    leak detectors such as valgrind to ignore our deliberate "leaks".
    
    The memory returned by leaky_*() must not be free'd.
    
    Build system and PCB integration, and leaky_atexit.c reindenting by
    Peter Clifton <pcjc2@xxxxxxxxx>

diff --git a/src/Makefile.am b/src/Makefile.am
index a0f1c50..e287ae7 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -72,6 +72,8 @@ PCB_SRCS = \
 	find.h \
 	flags.c \
 	fontmode.c \
+	free_atexit.c \
+	free_atexit.h \
 	global.h \
 	heap.c \
 	heap.h \
diff --git a/src/free_atexit.c b/src/free_atexit.c
new file mode 100644
index 0000000..dc11f12
--- /dev/null
+++ b/src/free_atexit.c
@@ -0,0 +1,91 @@
+/*                            COPYRIGHT
+ *
+ *  Copyright (C) 2010 PCB Contributors (see ChangeLog for details)
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  Contact addresses for paper mail and Email:
+ *  harry eaton, 6697 Buttonhole Ct, Columbia, MD 21044 USA
+ *  haceaton@xxxxxxxxxxxxxxxxxx
+ *
+ */
+
+
+#include <stdlib.h>
+
+/* we need one ID per context - short int with 64k IDs should be enough */
+typedef unsigned int leaky_idx_t;
+
+
+/* This structure should be as big as void *, which should be the natural
+bit-width of the architecture. We allocate extra admin space to be as big
+as this union, to preserve alignment of pointers returned by malloc().
+NOTE: in the special corner case when leaky_idx_t is wider than void * but
+not multiple of it, the alignment will be messed up, potentially causing slower
+memory access. */
+typedef union {
+  leaky_idx_t idx;
+  void *ptr;
+} leaky_admin_t;
+
+static void         **free_list = NULL;
+static leaky_idx_t  free_size = 0;
+
+
+void *leaky_malloc (size_t size)
+{
+  void *new_memory = malloc(size + sizeof(leaky_admin_t));
+
+  free_list = realloc (free_list, (free_size + 1) * sizeof(void *));
+  free_list[free_size] = new_memory;
+  *(leaky_idx_t *)new_memory = free_size;
+
+  free_size++;
+  return new_memory + sizeof(leaky_admin_t);
+}
+
+void *leaky_realloc (void* old_memory, size_t size)
+{
+  void *new_memory;
+  leaky_idx_t i;
+
+  if (old_memory == NULL)
+    return leaky_malloc (size);
+
+  old_memory -= sizeof(leaky_admin_t);
+
+  i = *(leaky_idx_t *)old_memory;
+
+  new_memory = realloc (old_memory, size + sizeof(leaky_admin_t));
+  free_list[i] = new_memory;
+
+  return new_memory + sizeof(leaky_admin_t);
+}
+
+void leaky_uninit (void)
+{
+  int i;
+
+  for (i = 0; i < free_size; i++)
+    free (free_list[i]);
+
+  free (free_list);
+  free_size = 0;
+}
+
+void leaky_init (void)
+{
+  atexit(leaky_uninit);
+}
diff --git a/src/free_atexit.h b/src/free_atexit.h
new file mode 100644
index 0000000..3b142b6
--- /dev/null
+++ b/src/free_atexit.h
@@ -0,0 +1,30 @@
+/* This tiny library is to assist cleaning up harmless memory leaks caused
+   by (growing) buffers allocated in static variables in functions. The
+   library provides leaky_ prefixed variants of the common allocation
+   routines. These wrappers will remember all pointers they return and
+   can free all memory used, at the end of the applocation.
+*/
+
+#include <stdlib.h>
+
+#ifdef NDEBUG
+#define leaky_init()
+#define leaky_uninit()
+#define leaky_malloc(size) malloc(size)
+#define leaky_realloc(ptr, size) malloc(ptr, size)
+#else
+
+/* set up atexit() hook - can be avoided if leaky_uninit() is called by hand */
+void leaky_init (void);
+
+/* free all allocations */
+void leaky_uninit (void);
+
+/* allocate memory, remember the pointer and free it after exit from the application */
+void *leaky_malloc (size_t size);
+
+/* reallocate memory, remember the new pointer and free it after exit from the application */
+void *leaky_realloc (void* old_memory, size_t size);
+
+
+#endif
diff --git a/src/main.c b/src/main.c
index 462285d..735fde7 100644
--- a/src/main.c
+++ b/src/main.c
@@ -53,6 +53,7 @@
 #include "action.h"
 #include "misc.h"
 #include "lrealpath.h"
+#include "free_atexit.h"
 
 #include "hid/common/actions.h"
 
@@ -1028,6 +1029,13 @@ main (int argc, char *argv[])
   /*    FIX_ME
      LoadBackgroundImage (Settings.BackgroundImage); */
 
+  /* This must be called before any other atexit functions
+   * are registered, as it configures an atexit function to
+   * clean up and free various items of allocated memory,
+   * and must be the last last atexit function to run.
+   */
+  leaky_init ();
+
   /* Register a function to be called when the program terminates.
    * This makes sure that data is saved even if LEX/YACC routines
    * abort the program.




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