summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Jennings <mej@lbl.gov>2013-03-22 17:10:10 -0700
committerMichael Jennings <mej@lbl.gov>2013-03-22 17:10:10 -0700
commitaec69ba959f1ce3cb0cd87b2ba8fc786089dd521 (patch)
tree0e0fb6f76a4305de3b44bf7944b8a3abeb1f5a22
parent9f1e27591d9f03d78af7ac3a9343a3782de0f2f4 (diff)
downloadlibast-devs/mej/malloc-tracking-removal.tar.gz
Working on rewrite of memory subsystem.devs/mej/malloc-tracking-removal
-rw-r--r--configure.ac2
-rw-r--r--include/libast.h321
-rw-r--r--include/libast/sysdefs.h.in5
-rw-r--r--libast.m464
-rw-r--r--src/Makefile.am2
-rw-r--r--src/mem.c760
6 files changed, 162 insertions, 992 deletions
diff --git a/configure.ac b/configure.ac
index 167ed0d..9ea4deb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -87,8 +87,6 @@ AC_TRY_RUN([
AC_MSG_RESULT([no - assumed because cross-compiling])
])
-AST_X11_SUPPORT()
-AST_IMLIB2_SUPPORT()
AST_MMX_SUPPORT()
AST_ARG_REGEXP(REGEXP)
AST_ARG_BACKQUOTE_EXEC(ALLOW_BACKQUOTE_EXEC)
diff --git a/include/libast.h b/include/libast.h
index d966df3..d133be8 100644
--- a/include/libast.h
+++ b/include/libast.h
@@ -967,118 +967,6 @@ extern int re_exec();
/********************************* MEM GOOP ***********************************/
/**
- * @def MALLOC(sz)
- * Allocate @a sz bytes of memory.
- *
- * This macro is a replacement for the libc function malloc(). It
- * allocates the specified number of bytes of memory on the heap and
- * returns a pointer to that memory location. This macro calls libc's
- * malloc() if memory debugging is off, and spifmem_malloc() if it's
- * on.
- *
- * @param sz The size in bytes of the block of memory to allocate.
- * @return A pointer to the allocated memory.
- * @see @link DOXGRP_MEM Memory Management Subsystem @endlink
- * @ingroup DOXGRP_MEM
- */
-/**
- * @def CALLOC(type, n)
- * Allocate enough memory for @a n objects of type @a type.
- *
- * This macro is a replacement for the libc function calloc(). It
- * allocates a block of memory on the heap large enough to hold @a n
- * objects of type @a type (e.g., a @a type array of size @a n). The
- * memory area is zeroed out prior to the pointer to it being
- * returned. This macro calls libc's calloc() if memory debugging is
- * off and spifmem_calloc() if it's on.
- *
- * @param type The type of object to be allocated (e.g., int).
- * @param n The number of objects to be allocated.
- * @return A pointer to the allocated memory.
- * @see @link DOXGRP_MEM Memory Management Subsystem @endlink
- * @ingroup DOXGRP_MEM
- */
-/**
- * @def REALLOC(mem, sz)
- * Resize the memory block pointed to by @a mem to @a sz bytes.
- *
- * This macro is a replacement for the libc function realloc(). It
- * changes the size of a chunk of memory previously allocated by
- * malloc() or calloc() (or, by extension, the MALLOC()/CALLOC()
- * macros) and returns a pointer to the (possibly moved) memory area.
- * This macro calls libc's realloc() if memory debugging is off and
- * spifmem_realloc() if it's on.
- *
- * @param mem The old pointer whose size will be changed.
- * @param sz The new size, in bytes, to be allocated.
- * @return The new pointer value, which may or may not differ from the
- * old value.
- * @see @link DOXGRP_MEM Memory Management Subsystem @endlink
- * @ingroup DOXGRP_MEM
- */
-/**
- * @def FREE(ptr)
- * Free a previously-allocated memory block.
- *
- * This macro is a replacement for the libc function free(). It
- * returns the previously-allocated memory block pointed to by @a ptr
- * to the heap. This macro calls libc's free() if memory debugging is
- * off and spifmem_free() if it's on. The @a ptr parameter is assigned
- * the value of NULL after it has been freed.
- *
- * @param ptr The pointer to be freed.
- * @see @link DOXGRP_MEM Memory Management Subsystem @endlink
- * @ingroup DOXGRP_MEM
- */
-/**
- * @def ALLOCA(sz)
- * Allocate @a sz bytes of memory on the stack.
- *
- * This macro is a replacement for the libc function alloca(). It
- * allocates the specified number of bytes of memory on the stack and
- * returns a pointer to that memory location. This macro calls libc's
- * alloca() if memory debugging is off, and wraps it if it's
- * on.
- *
- * @param sz The size in bytes of the block of memory to allocate.
- * @return A pointer to the allocated memory.
- * @see @link DOXGRP_MEM Memory Management Subsystem @endlink
- * @ingroup DOXGRP_MEM
- */
-/**
- * @def STRDUP(s)
- * Duplicate a string pointer and return a pointer to the new copy.
- *
- * This macro is a replacement for the libc function strdup(). It
- * allocates a section of memory large enough to hold the string @a s
- * (including the trailing NUL character), copies the contents of @a s
- * into the new buffer, and returns a pointer to the new copy. This
- * macro calls libc's strdup() of memory debugging is off and
- * spifmem_strdup() if it's on.
- *
- * @param s The string to duplicate.
- * @return A pointer to the newly-created copy.
- * @see @link DOXGRP_MEM Memory Management Subsystem @endlink
- * @ingroup DOXGRP_MEM
- */
-/**
- * @def MALLOC_DUMP()
- * Dumps a listing of all allocated pointers along with their sizes
- * and contents in both hex and ASCII.
- *
- * This macro is used to view the status of memory allocated via the
- * LibAST memory management system. First the pointers used to track
- * allocated memory are dumped (that's what pointer #0 is); then, each
- * allocated pointer is dumped along with its size and contents, the
- * latter being displayed both in hexadecimal form and ASCII form.
- * Non-printable characters are replaced by dots ('.'). You can see
- * a sample of the output in the
- * @link mem_example.c memory management system example @endlink.
- *
- * @see @link DOXGRP_MEM Memory Management Subsystem @endlink
- * @ingroup DOXGRP_MEM
- */
-/**
* @def X_CREATE_PIXMAP(d, win, w, h, depth)
* Create an X pixmap.
*
@@ -1194,119 +1082,79 @@ extern int re_exec();
* @see @link DOXGRP_MEM Memory Management Subsystem @endlink
* @ingroup DOXGRP_MEM
*/
-/**
- * @def MALLOC_CALL_INTERVAL
- * MALLOC() call count interval.
- *
- * LibAST has the ability to count calls to MALLOC(); this defines the
- * interval for reporting the call count. The default is 25, meaning
- * that LibAST will print the current count every 25 calls. Note that
- * MALLOC_CALL_COUNT must be defined when compiling LibAST, in
- * addition to memory debugging, for this feature to work.
- *
- * @see @link DOXGRP_MEM Memory Management Subsystem @endlink
- * @ingroup DOXGRP_MEM
- */
-/**
- * @def REALLOC_CALL_INTERVAL
- * REALLOC() call count interval.
- *
- * LibAST has the ability to count calls to REALLOC(); this defines
- * the interval for reporting the call count. The default is 25,
- * meaning that LibAST will print the current count every 25 calls.
- * Note that MALLOC_CALL_COUNT must be defined when compiling LibAST,
- * in addition to memory debugging, for this feature to work.
- *
- * @see @link DOXGRP_MEM Memory Management Subsystem @endlink
- * @ingroup DOXGRP_MEM
- */
-/**
- * @def CALLOC_CALL_INTERVAL
- * CALLOC() call count interval.
- *
- * LibAST has the ability to count calls to CALLOC(); this defines the
- * interval for reporting the call count. The default is 25, meaning
- * that LibAST will print the current count every 25 calls. Note that
- * MALLOC_CALL_COUNT must be defined when compiling LibAST, in
- * addition to memory debugging, for this feature to work.
- *
- * @see @link DOXGRP_MEM Memory Management Subsystem @endlink
- * @ingroup DOXGRP_MEM
- */
-/**
- * @def FREE_CALL_INTERVAL
- * FREE() call count interval.
- *
- * LibAST has the ability to count calls to FREE(); this defines the
- * interval for reporting the call count. The default is 25, meaning
- * that LibAST will print the current count every 25 calls. Note that
- * MALLOC_CALL_COUNT must be defined when compiling LibAST, in
- * addition to memory debugging, for this feature to work.
- *
- * @see @link DOXGRP_MEM Memory Management Subsystem @endlink
- * @ingroup DOXGRP_MEM
- */
#if (DEBUG >= DEBUG_MEM)
-# define MALLOC(sz) spifmem_malloc(__FILE__, __LINE__, (sz))
-# define CALLOC(type,n) spifmem_calloc(__FILE__, __LINE__, (n), (sizeof(type)))
-# define REALLOC(mem,sz) spifmem_realloc(#mem, __FILE__, __LINE__, (mem), (sz))
-# define FREE(ptr) do { spifmem_free(#ptr, __FILE__, __LINE__, (ptr)); (ptr) = NULL; } while (0)
# ifdef LIBAST_SUPPORT_MACRO_CSE
-# define ALLOCA(sz) ({ void *p = alloca(sz); p; })
-# else
-# define ALLOCA(sz) alloca(sz)
-# endif
-# define STRDUP(s) spifmem_strdup(#s, __FILE__, __LINE__, (s))
-# define MALLOC_DUMP() spifmem_dump_mem_tables()
/* X11 Wrappers */
-# if 0 && defined(LIBAST_SUPPORT_MACRO_CSE)
# define X_CREATE_PIXMAP(d, win, w, h, depth) ({ \
- Pixmap p = XCreatePixmap((d), (win), (w), (h), (depth)); \
- D_MEM(("Created %ux%u pixmap 0x%08x of depth %u for window 0x%08x at %s:%lu\n", (w), (h), p, (depth), (win), __FILE__, __LINE__)); \
- if (p == None) return p; \
- memrec_add_var(&pixmap_rec, (spif_charptr_t) NONULL(filename), line, (void *) p, w * h * (depth / 8)); \
- p; \
- })
-# endif
-# define X_CREATE_PIXMAP(d, win, w, h, depth) spifmem_x_create_pixmap(__FILE__, __LINE__, (d), (win), (w), (h), (depth))
-# define X_FREE_PIXMAP(d, p) spifmem_x_free_pixmap(#p, __FILE__, __LINE__, (d), (p))
-# if LIBAST_IMLIB2_SUPPORT
-# define IMLIB_REGISTER_PIXMAP(p) spifmem_imlib_register_pixmap(#p, __FILE__, __LINE__, (p))
-# define IMLIB_FREE_PIXMAP(p) spifmem_imlib_free_pixmap(#p, __FILE__, __LINE__, (p))
-# else
-# define IMLIB_REGISTER_PIXMAP(p) NOP
-# define IMLIB_FREE_PIXMAP(p) NOP
-# endif
-# define PIXMAP_DUMP() spifmem_dump_pixmap_tables()
-# define X_CREATE_GC(d, win, f, gcv) spifmem_x_create_gc(__FILE__, __LINE__, (d), (win), (f), (gcv))
-# define X_FREE_GC(d, gc) spifmem_x_free_gc(#gc, __FILE__, __LINE__, (d), (gc))
-# define GC_DUMP() spifmem_dump_gc_tables()
-# define MALLOC_CALL_INTERVAL 25
-# define REALLOC_CALL_INTERVAL 25
-# define CALLOC_CALL_INTERVAL 25
-# define FREE_CALL_INTERVAL 25
+ Pixmap p = XCreatePixmap((d), (win), (w), (h), (depth)); \
+ D_MEM(("Created %ux%u pixmap 0x%08x of depth %u for window 0x%08x at %s:%lu\n", \
+ (w), (h), p, (depth), (win), __FILE__, __LINE__)); \
+ if (p && (DEBUG_LEVEL >= DEBUG_MEM)) spifmem_add_var(__FILE__, __LINE__, (void *) p, w * h * (depth / 8), "X Pixmap"); \
+ p; \
+ })
+# define X_FREE_PIXMAP(d, p) do { \
+ D_MEM(("Freeing pixmap %s (0x%08x) at %s:%lu\n", #p, p, __FILE__, __LINE__)); \
+ if (p) { \
+ if (DEBUG_LEVEL >= DEBUG_MEM) spifmem_rem_var(#p, __FILE__, __LINE__, (p)); \
+ XFreePixmap((d), (p)); \
+ } else { \
+ D_MEM(("ERROR: Caught attempt to free NULL pixmap\n")); \
+ } \
+ } while (0)
+# define X_CREATE_GC(d, win, f, gcv) ({ \
+ GC gc = XCreateGC((d), (win), (mask), (gcv)); \
+ D_MEM(("Created gc 0x%08x for window 0x%08x at %s:%lu\n", (int) gc, (win), __FILE__, __LINE__)); \
+ if (gc && (DEBUG_LEVEL >= DEBUG_MEM)) spifmem_add_var(__FILE__, __LINE__, (void *) gc, sizeof(XGCValues), "X GC"); \
+ gc; \
+ })
+# define X_FREE_GC(d, gc) do { \
+ D_MEM(("Freeing GC %s (0x%08x) at %s:%lu\n", #gc, gc, __FILE__, __LINE__)); \
+ if (gc) { \
+ if (DEBUG_LEVEL >= DEBUG_MEM) spifmem_rem_var(#gc, __FILE__, __LINE__, (gc)); \
+ XFreeGC((d), (gc)); \
+ } else { \
+ D_MEM(("ERROR: Caught attempt to free NULL GC\n")); \
+ } \
+ } while (0)
+# else /* LIBAST_SUPPORT_MACRO_CSE */
+# define X_CREATE_PIXMAP(d, win, w, h, depth) XCreatePixmap((d), (win), (w), (h), (depth))
+# define X_FREE_PIXMAP(d, p) XFreePixmap((d), (p))
+# define X_CREATE_GC(d, win, f, gcv) XCreateGC((d), (win), (f), (gcv))
+# define X_FREE_GC(d, gc) XFreeGC((d), (gc))
+# endif /* LIBAST_SUPPORT_MACRO_CSE */
+# define IMLIB_REGISTER_PIXMAP(p) do { \
+ D_MEM(("Registering pixmap %s (0x%08x) created by Imlib2 at %s:%lu\n", #p, p, __FILE__, __LINE__)); \
+ if (p) { \
+ if (DEBUG_LEVEL >= DEBUG_MEM) { \
+ if (!spifmem_find_var((void *) p)) { \
+ spifmem_add_var(__FILE__, __LINE__, (void *) p, 1, "Imlib2 Pixmap"); \
+ } else { \
+ D_MEM(("Pixmap 0x%08x already registered.\n", p)); \
+ } \
+ } \
+ } else { \
+ D_MEM(("ERROR: Refusing to register a NULL pixmap\n")); \
+ } \
+ } while (0)
+# define IMLIB_FREE_PIXMAP(p) do { \
+ D_MEM(("Freeing pixmap %s (0x%08x) at %s:%lu using Imlib2\n", #p, p, __FILE__, __LINE__)); \
+ if (p) { \
+ if (DEBUG_LEVEL >= DEBUG_MEM) spifmem_rem_var(#p, __FILE__, __LINE__, (p)); \
+ imlib_free_pixmap_and_mask(p); \
+ } else { \
+ D_MEM(("ERROR: Caught attempt to free NULL pixmap\n")); \
+ } \
+ } while (0)
+# define SPIFMEM_DUMP() spifmem_dump_resources()
#else
-# define MALLOC(sz) malloc(sz)
-# define CALLOC(type,n) calloc((n),(sizeof(type)))
-# define REALLOC(mem,sz) ((sz) ? ((mem) ? (realloc((mem), (sz))) : (malloc(sz))) : ((mem) ? (free(mem), NULL) : (NULL)))
-# define FREE(ptr) do { free(ptr); (ptr) = NULL; } while (0)
-# define ALLOCA(sz) alloca(sz)
-# define STRDUP(s) strdup((char *) s)
-# define MALLOC_DUMP() NOP
# define X_CREATE_PIXMAP(d, win, w, h, depth) XCreatePixmap((d), (win), (w), (h), (depth))
# define X_FREE_PIXMAP(d, p) XFreePixmap((d), (p))
-# ifdef LIBAST_IMLIB2_SUPPORT
-# define IMLIB_REGISTER_PIXMAP(p) NOP
-# define IMLIB_FREE_PIXMAP(p) imlib_free_pixmap_and_mask(p)
-# else
-# define IMLIB_REGISTER_PIXMAP(p) NOP
-# define IMLIB_FREE_PIXMAP(p) NOP
-# endif
-# define PIXMAP_DUMP() NOP
# define X_CREATE_GC(d, win, f, gcv) XCreateGC((d), (win), (f), (gcv))
# define X_FREE_GC(d, gc) XFreeGC((d), (gc))
-# define GC_DUMP() NOP
+# define IMLIB_REGISTER_PIXMAP(p) NOP
+# define IMLIB_FREE_PIXMAP(p) imlib_free_pixmap_and_mask(p)
+# define SPIFMEM_DUMP() NOP
#endif
/**
@@ -1329,7 +1177,6 @@ extern int re_exec();
* track of what pointers have been allocated, where they were
* allocated, and how much space was requested.
*
- * @see MALLOC(), REALLOC(), CALLOC(), FREE()
* @ingroup DOXGRP_MEM
*/
typedef struct spifmem_ptr_t {
@@ -1337,6 +1184,8 @@ typedef struct spifmem_ptr_t {
void *ptr;
/** The pointer's size, in bytes. The pointer's size, in bytes. */
size_t size;
+ /** The resource type. The resource type. */
+ char *type;
/** Filename. The file which last (re)allocated the pointer. */
spif_char_t file[SPIFMEM_FNAME_LEN + 1];
/** Line number. The line number where the pointer was last (re)allocated. */
@@ -2837,30 +2686,11 @@ extern unsigned int DEBUG_LEVEL;
/* mem.c */
extern void spifmem_init(void);
-extern void memrec_add_var(spifmem_memrec_t *, const char *, unsigned long, void *, size_t);
-extern spifmem_ptr_t *memrec_find_var(spifmem_memrec_t *, const void *);
-extern void memrec_rem_var(spifmem_memrec_t *, const char *, const char *, unsigned long, const void *);
-extern void memrec_chg_var(spifmem_memrec_t *, const char *, const char *, unsigned long, const void *, void *, size_t);
-extern void memrec_dump_pointers(spifmem_memrec_t *);
-extern void memrec_dump_resources(spifmem_memrec_t *);
-extern void *spifmem_malloc(const char *, unsigned long, size_t);
-extern void *spifmem_realloc(const char *, const char *, unsigned long, void *, size_t);
-extern void *spifmem_calloc(const char *, unsigned long, size_t, size_t);
-extern void spifmem_free(const char *, const char *, unsigned long, void *);
-extern char *spifmem_strdup(const char *, const char *, unsigned long, const char *);
-extern void spifmem_dump_mem_tables(void);
-#if LIBAST_X11_SUPPORT
-extern Pixmap spifmem_x_create_pixmap(const char *, unsigned long, Display *, Drawable, unsigned int, unsigned int, unsigned int);
-extern void spifmem_x_free_pixmap(const char *, const char *, unsigned long, Display *, Pixmap);
-# if LIBAST_IMLIB2_SUPPORT
-extern void spifmem_imlib_register_pixmap(const char * var, const char * filename, unsigned long line, Pixmap p);
-extern void spifmem_imlib_free_pixmap(const char * var, const char * filename, unsigned long line, Pixmap p);
-# endif
-extern void spifmem_dump_pixmap_tables(void);
-extern GC spifmem_x_create_gc(const char *, unsigned long, Display *, Drawable, unsigned long, XGCValues *);
-extern void spifmem_x_free_gc(const char *, const char *, unsigned long, Display *, GC);
-extern void spifmem_dump_gc_tables(void);
-#endif
+extern void spifmem_add_var(const char *, unsigned long, void *, size_t, char *);
+extern spifmem_ptr_t *spifmem_find_var(const void *);
+extern void spifmem_rem_var(const char *, const char *, unsigned long, const void *);
+extern void spifmem_chg_var(const char *, const char *, unsigned long, const void *, void *, size_t);
+extern void spifmem_dump_resources(void);
extern void spiftool_free_array(void *, size_t);
/* file.c */
@@ -3016,4 +2846,15 @@ static void (*fatal_error)(const char *, ...) = libast_fatal_error;
#endif /* LIBAST_COMPAT_05_API */
+#if LIBAST_COMPAT_07_API
+# define MALLOC(sz) malloc(sz)
+# define CALLOC(type,n) calloc((n),(sizeof(type)))
+# define REALLOC(mem,sz) ((sz) ? ((mem) ? (realloc((mem), (sz))) : (malloc(sz))) : ((mem) ? (free(mem), NULL) : (NULL)))
+# define FREE(ptr) do { free(ptr); (ptr) = NULL; } while (0)
+# define STRDUP(s) strdup((char *) s)
+# define MALLOC_DUMP() NOP
+# define PIXMAP_DUMP() SPIFMEM_DUMP()
+# define GC_DUMP() SPIFMEM_DUMP()
+#endif /* LIBAST_COMPAT_07_API */
+
#endif /* _LIBAST_H_ */
diff --git a/include/libast/sysdefs.h.in b/include/libast/sysdefs.h.in
index 4344abd..320d7f3 100644
--- a/include/libast/sysdefs.h.in
+++ b/include/libast/sysdefs.h.in
@@ -96,6 +96,11 @@
# define LIBAST_COMPAT_05_API 0
#endif
+/* App-definable; requests 0.7 API compatibility. */
+#ifndef LIBAST_COMPAT_07_API
+# define LIBAST_COMPAT_07_API 0
+#endif
+
/* A bunch of security checks. */
#ifndef HAVE_RLIMIT_MEMLOCK
# define HAVE_RLIMIT_MEMLOCK 0
diff --git a/libast.m4 b/libast.m4
index bc604fa..f900061 100644
--- a/libast.m4
+++ b/libast.m4
@@ -179,74 +179,14 @@ dnl#
dnl# LibAST macro for X11 support
dnl#
AC_DEFUN([AST_X11_SUPPORT], [
- AC_PATH_XTRA
- if test ! -z "$X_CFLAGS"; then
- if test -z "$CPPFLAGS"; then
- CPPFLAGS="$X_CFLAGS"
- else
- CPPFLAGS="$CPPFLAGS $X_CFLAGS"
- fi
- fi
- if test ! -z "$X_LIBS"; then
- if test -z "$LDFLAGS"; then
- LDFLAGS="$X_LIBS"
- else
- LDFLAGS="$LDFLAGS $X_LIBS"
- fi
- fi
- LIBAST_X11_SUPPORT=""
- if test "x$no_x" != "xyes"; then
- AC_CHECK_LIB(X11, XOpenDisplay, [
- LIBAST_X11_SUPPORT="X11"
- GRLIBS="-lX11"
- AC_DEFINE([LIBAST_X11_SUPPORT], [1], [Define for X11 support.])
- ])
- fi
- AC_SUBST(LIBAST_X11_SUPPORT)
+ :
])
dnl#
dnl# LibAST macro for Imlib2 support
dnl#
AC_DEFUN([AST_IMLIB2_SUPPORT], [
- AC_ARG_WITH(imlib,
- [ --with-imlib[=DIR] compile with Imlib2 support (default)],
- [
- if test "$withval" != "no"; then
- if test "$withval" != "yes"; then
- CPPFLAGS="$CPPFLAGS -I${withval}/include"
- LDFLAGS="$LDFLAGS -L${withval}/lib"
- fi
- USE_IMLIB=1
- else
- USE_IMLIB=0
- fi
- ], [
- USE_IMLIB=1
- ])
- LIBAST_IMLIB2_SUPPORT=""
- if test $USE_IMLIB -eq 1 ; then
- AC_CHECK_PROG(IMLIB2_CONFIG, imlib2-config, imlib2-config)
- if test "x$IMLIB2_CONFIG" != "x"; then
- GRLIBS="`$IMLIB2_CONFIG --libs`"
- CFLAGS="$CFLAGS `$IMLIB2_CONFIG --cflags`"
- AC_DEFINE([LIBAST_IMLIB2_SUPPORT], [1], [Define for Imlib2 support.])
- LIBAST_IMLIB2_SUPPORT="Imlib2"
- else
- AC_CHECK_LIB(m, pow, LIBS="-lm $LIBS")
- AC_CHECK_LIB(dl, dlopen, LIBS="-ldl $LIBS")
- AC_CHECK_LIB(freetype, FT_Init_FreeType, GRLIBS="-lfreetype $GRLIBS", , $GRLIBS)
- AC_CHECK_LIB(Imlib2, imlib_create_image, [
- GRLIBS="-lImlib2 $GRLIBS"
- AC_DEFINE([LIBAST_IMLIB2_SUPPORT], [1], [Define for Imlib2 support.])
- LIBAST_IMLIB2_SUPPORT="Imlib2"
- ], [
- AC_WARN(*** Imlib2 support has been disabled because Imlib2 ***)
- AC_WARN(*** was not found or could not be linked. ***)
- ], $GRLIBS)
- fi
- fi
- AC_SUBST(LIBAST_IMLIB2_SUPPORT)
+ :
])
dnl#
diff --git a/src/Makefile.am b/src/Makefile.am
index c8ecfaf..5f61d33 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -11,5 +11,5 @@ dlinked_list.c file.c linked_list.c mbuff.c mem.c module.c msgs.c \
obj.c objpair.c options.c pthreads.c regexp.c socket.c str.c strings.c \
snprintf.c tok.c url.c ustr.c
-libast_la_LDFLAGS = -version-info 2:2:0
+libast_la_LDFLAGS = -version-info 3:0:0
MAINTAINERCLEANFILES = Makefile.in
diff --git a/src/mem.c b/src/mem.c
index 083ab2e..f0fbf61 100644
--- a/src/mem.c
+++ b/src/mem.c
@@ -36,62 +36,15 @@
#include "libast_internal.h"
-#if MALLOC_CALL_COUNT
-/*@{*/
/**
- * @name Memory Management Call Tracking
- * Count calls to memory management functions.
+ * Allocated resources.
*
- * This group of variables is used to count calls to the memory
- * management functions. Call counting is controlled by the
- * #MALLOC_CALL_COUNT symbol, and is off by default.
- *
- * @see @link DOXGRP_MEM Memory Management Subsystem @endlink
- * @ingroup DOXGRP_MEM
- */
-
-/** Count calls to MALLOC(). Count calls to MALLOC(). */
-static int malloc_count = 0;
-/** Count calls to CALLOC(). Count calls to CALLOC(). */
-static int calloc_count = 0;
-/** Count calls to REALLOC(). Count calls to REALLOC(). */
-static int realloc_count = 0;
-/** Count calls to FREE(). Count calls to FREE(). */
-static int free_count = 0;
-/*@}*/
-#endif
-
-/**
- * Allocated pointers.
- *
- * This structure keeps track of the pointer array which represents
- * pointers allocated via the memory management interface.
- *
- * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, spifmem_memrec_t_struct
- * @ingroup DOXGRP_MEM
- */
-static spifmem_memrec_t malloc_rec;
-/**
- * Allocated pixmaps.
- *
- * This structure keeps track of the pixmap array which represents
- * pixmaps allocated via the memory management interface.
+ * This structure keeps track of generic resources.
*
* @see @link DOXGRP_MEM Memory Management Subsystem @endlink, spifmem_memrec_t_struct
* @ingroup DOXGRP_MEM
*/
-static spifmem_memrec_t pixmap_rec;
-/**
- * Allocated GC's.
- *
- * This structure keeps track of the GC array which represents
- * X11 Graphics Context objects, or GC's, allocated via the memory
- * management interface.
- *
- * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, spifmem_memrec_t_struct
- * @ingroup DOXGRP_MEM
- */
-static spifmem_memrec_t gc_rec;
+static spifmem_memrec_t resource_rec;
/**
* Initialize memory management system.
@@ -107,55 +60,46 @@ void
spifmem_init(void)
{
D_MEM(("Constructing memory allocation records\n"));
- malloc_rec.ptrs = (spifmem_ptr_t *) malloc(sizeof(spifmem_ptr_t));
- pixmap_rec.ptrs = (spifmem_ptr_t *) malloc(sizeof(spifmem_ptr_t));
- gc_rec.ptrs = (spifmem_ptr_t *) malloc(sizeof(spifmem_ptr_t));
+ resource_rec.ptrs = (spifmem_ptr_t *) malloc(sizeof(spifmem_ptr_t));
}
/**
- * Add a variable to a record set.
+ * Add a resource to be tracked.
*
- * This is the static, internal-use-only function that does the actual
- * work of recording information on a variable to be tracked. This
- * information includes file and line number information and is stored
- * as a #spifmem_ptr_t.
- *
- * @param memrec Address of the #spifmem_memrec_t we're adding to.
* @param filename The filename where the variable was allocated.
* @param line The line number of @a filename where the variable
* was allocated.
* @param ptr The allocated variable.
- * @param size The number of bytes requested.
+ * @param size The size of the resource in bytes.
+ * @param type The type of resource being tracked.
*
* @see @link DOXGRP_MEM Memory Management Subsystem @endlink, MALLOC(), libast_malloc()
* @ingroup DOXGRP_MEM
*/
void
-memrec_add_var(spifmem_memrec_t *memrec, const char *filename, unsigned long line, void *ptr, size_t size)
+spifmem_add_var(const char *filename, unsigned long line, void *ptr, size_t size, char *type)
{
register spifmem_ptr_t *p;
- ASSERT(memrec != NULL);
- memrec->cnt++;
- if (!(memrec->ptrs = (spifmem_ptr_t *)realloc(memrec->ptrs, sizeof(spifmem_ptr_t) * memrec->cnt))) {
+ resource_rec.cnt++;
+ if (!(resource_rec.ptrs = (spifmem_ptr_t *)realloc(resource_rec.ptrs, sizeof(spifmem_ptr_t) * resource_rec.cnt))) {
D_MEM(("Unable to reallocate pointer list -- %s\n", strerror(errno)));
}
- p = memrec->ptrs + memrec->cnt - 1;
+ p = resource_rec.ptrs + resource_rec.cnt - 1;
D_MEM(("Adding variable (%10p, %lu bytes) from %s:%lu.\n", ptr, size, filename, line));
- D_MEM(("Storing as pointer #%lu at %10p (from %10p).\n", memrec->cnt, p, memrec->ptrs));
+ D_MEM(("Storing as pointer #%lu at %10p (from %10p).\n", resource_rec.cnt, p, resource_rec.ptrs));
p->ptr = ptr;
p->size = size;
spiftool_safe_strncpy(p->file, (const spif_charptr_t) filename, sizeof(p->file));
p->line = line;
+ p->type = type;
}
/**
- * Find a variable within a record set.
+ * Find a variable within the list of tracked resources.
*
- * This function searches through the pointer list of the specified
- * @a memrec object for a given pointer.
+ * This function searches through the resource list for a given resource ID.
*
- * @param memrec Address of the #spifmem_memrec_t we're searching.
* @param ptr The value of the requested pointer.
* @return A pointer to the #spifmem_ptr_t object within @a memrec
* that matches @a ptr, or NULL if not found.
@@ -164,17 +108,16 @@ memrec_add_var(spifmem_memrec_t *memrec, const char *filename, unsigned long lin
* @ingroup DOXGRP_MEM
*/
spifmem_ptr_t *
-memrec_find_var(spifmem_memrec_t *memrec, const void *ptr)
+spifmem_find_var(const void *ptr)
{
register spifmem_ptr_t *p;
register unsigned long i;
- ASSERT_RVAL(memrec != NULL, NULL);
REQUIRE_RVAL(ptr != NULL, NULL);
- for (i = 0, p = memrec->ptrs; i < memrec->cnt; i++, p++) {
+ for (i = 0, p = resource_rec.ptrs; i < resource_rec.cnt; i++, p++) {
if (p->ptr == ptr) {
- D_MEM(("Found pointer #%lu stored at %10p (from %10p)\n", i + 1, p, memrec->ptrs));
+ D_MEM(("Found pointer #%lu stored at %10p (from %10p)\n", i + 1, p, resource_rec.ptrs));
return p;
}
}
@@ -182,12 +125,8 @@ memrec_find_var(spifmem_memrec_t *memrec, const void *ptr)
}
/**
- * Remove a variable from a record set.
- *
- * This is the static, internal-use-only function that does the actual
- * work of freeing recorded information for a deleted pointer.
+ * Remove a variable from the list of tracked resources.
*
- * @param memrec Address of the #spifmem_memrec_t we're removing from.
* @param var The variable name being freed (for diagnostic
* purposes only).
* @param filename The filename where the variable was freed.
@@ -199,34 +138,29 @@ memrec_find_var(spifmem_memrec_t *memrec, const void *ptr)
* @ingroup DOXGRP_MEM
*/
void
-memrec_rem_var(spifmem_memrec_t *memrec, const char *var, const char *filename, unsigned long line, const void *ptr)
+spifmem_rem_var(const char *var, const char *filename, unsigned long line, const void *ptr)
{
register spifmem_ptr_t *p;
- ASSERT(memrec != NULL);
USE_VAR(var);
USE_VAR(filename);
USE_VAR(line);
- if (!(p = memrec_find_var(memrec, ptr))) {
- D_MEM(("ERROR: File %s, line %d attempted to free variable %s (%10p) which was not allocated with MALLOC/REALLOC\n",
+ if (!(p = spifmem_find_var(ptr))) {
+ D_MEM(("ERROR: File %s, line %d attempted to free resource %s (%10p) which was not registered.\n",
filename, line, var, ptr));
return;
}
D_MEM(("Removing variable %s (%10p) of size %lu\n", var, ptr, p->size));
- if ((--memrec->cnt) > 0) {
- memmove(p, p + 1, sizeof(spifmem_ptr_t) * (memrec->cnt - (p - memrec->ptrs)));
- memrec->ptrs = (spifmem_ptr_t *) realloc(memrec->ptrs, sizeof(spifmem_ptr_t) * memrec->cnt);
+ if ((--resource_rec.cnt) > 0) {
+ memmove(p, p + 1, sizeof(spifmem_ptr_t) * (resource_rec.cnt - (p - resource_rec.ptrs)));
+ resource_rec.ptrs = (spifmem_ptr_t *) realloc(resource_rec.ptrs, sizeof(spifmem_ptr_t) * resource_rec.cnt);
}
}
/**
- * Resize a variable in a record set.
+ * Resize a tracked resource.
*
- * This is the static, internal-use-only function that does the actual
- * work of altering information on a tracked variable.
- *
- * @param memrec Address of the #spifmem_memrec_t we're modifying.
* @param var The variable name being resized (for diagnostic
* purposes only).
* @param filename The filename where the variable was resized.
@@ -240,143 +174,50 @@ memrec_rem_var(spifmem_memrec_t *memrec, const char *var, const char *filename,
* @ingroup DOXGRP_MEM
*/
void
-memrec_chg_var(spifmem_memrec_t *memrec, const char *var, const char *filename, unsigned long line, const void *oldp, void *newp, size_t size)
+spifmem_chg_var(const char *var, const char *filename, unsigned long line, const void *oldp, void *newp, size_t size)
{
register spifmem_ptr_t *p;
- ASSERT(memrec != NULL);
USE_VAR(var);
- if (!(p = memrec_find_var(memrec, oldp))) {
- D_MEM(("ERROR: File %s, line %d attempted to realloc variable %s (%10p) which was not allocated with MALLOC/REALLOC\n", filename,
+ if (!(p = spifmem_find_var(oldp))) {
+ D_MEM(("ERROR: File %s, line %d attempted to realloc untracked resource %s (%10p).\n", filename,
line, var, oldp));
return;
}
D_MEM(("Changing variable %s (%10p, %lu -> %10p, %lu)\n", var, oldp, p->size, newp, size));
p->ptr = newp;
p->size = size;
- spiftool_safe_strncpy(p->file, (const spif_charptr_t) filename, sizeof(p->file));
+ spiftool_safe_strncpy(p->file, filename, sizeof(p->file));
p->line = line;
}
/**
- * Dump listing of tracked pointers.
- *
- * This function dumps a listing of all pointers in @a memrec along
- * with the filename, line number, address, size, and contents for
- * each. Contents are displayed in both hex and ASCII, the latter
- * having non-printable characters replaced with periods ('.').
- *
- * @param memrec Address of the #spifmem_memrec_t we're dumping.
- *
- * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, MALLOC_DUMP(), libast_dump_mem_tables()
- * @ingroup DOXGRP_MEM
- */
-void
-memrec_dump_pointers(spifmem_memrec_t *memrec)
-{
- register spifmem_ptr_t *p;
- unsigned long i, j, k, l, total = 0;
- unsigned long len;
- spif_char_t buff[9];
-
- ASSERT(memrec != NULL);
- fprintf(LIBAST_DEBUG_FD, "PTR: %lu pointers stored.\n", (unsigned long) memrec->cnt);
- fprintf(LIBAST_DEBUG_FD,
- "PTR: Pointer | Filename | Line | Address | Size | Offset | 00 01 02 03 04 05 06 07 | ASCII \n");
- fprintf(LIBAST_DEBUG_FD,
- "PTR: ---------+----------------------+--------+----------+--------+---------+-------------------------+---------\n");
- fflush(LIBAST_DEBUG_FD);
- len = sizeof(spifmem_ptr_t) * memrec->cnt;
- memset(buff, 0, sizeof(buff));
-
- /* First, dump the contents of the memrec->ptrs[] array. */
- for (p = memrec->ptrs, j = 0; j < len; j += 8) {
- fprintf(LIBAST_DEBUG_FD, "PTR: %07lu | %20s | %6lu | %10p | %06lu | %07x | ",
- (unsigned long) 0, "", (unsigned long) 0,
- (spif_ptr_t) memrec->ptrs,
- (unsigned long) (sizeof(spifmem_ptr_t) * memrec->cnt), (unsigned int) j);
- /* l is the number of characters we're going to output */
- l = ((len - j < 8) ? (len - j) : (8));
- /* Copy l bytes (up to 8) from memrec->ptrs[] (p) to buffer */
- memcpy(buff, ((char *) p) + j, l);
- buff[l] = 0;
- for (k = 0; k < l; k++) {
- fprintf(LIBAST_DEBUG_FD, "%02x ", buff[k]);
- }
- /* If we printed less than 8 bytes worth, pad with 3 spaces per byte */
- for (; k < 8; k++) {
- fprintf(LIBAST_DEBUG_FD, " ");
- }
- /* Finally, print the printable ASCII string for those l bytes */
- fprintf(LIBAST_DEBUG_FD, "| %-8s\n", spiftool_safe_str((char *) buff, l));
- /* Flush after every line in case we crash */
- fflush(LIBAST_DEBUG_FD);
- }
-
- /* Now print out each pointer and its contents. */
- for (i = 0; i < memrec->cnt; p++, i++) {
- /* Add this pointer's size to our total */
- total += p->size;
- for (j = 0; j < p->size; j += 8) {
- fprintf(LIBAST_DEBUG_FD, "PTR: %07lu | %20s | %6lu | %10p | %06lu | %07x | ",
- i + 1, NONULL(p->file), (unsigned long) p->line,
- p->ptr, (unsigned long) p->size, (unsigned) j);
- /* l is the number of characters we're going to output */
- l = ((p->size - j < 8) ? (p->size - j) : (8));
- /* Copy l bytes (up to 8) from p->ptr to buffer */
- memcpy(buff, ((char *) p->ptr) + j, l);
- buff[l] = 0;
- for (k = 0; k < l; k++) {
- fprintf(LIBAST_DEBUG_FD, "%02x ", buff[k]);
- }
- /* If we printed less than 8 bytes worth, pad with 3 spaces per byte */
- for (; k < 8; k++) {
- fprintf(LIBAST_DEBUG_FD, " ");
- }
- /* Finally, print the printable ASCII string for those l bytes */
- fprintf(LIBAST_DEBUG_FD, "| %-8s\n", spiftool_safe_str(buff, l));
- /* Flush after every line in case we crash */
- fflush(LIBAST_DEBUG_FD);
- }
- }
- fprintf(LIBAST_DEBUG_FD, "PTR: Total allocated memory: %10lu bytes\n", total);
- fflush(LIBAST_DEBUG_FD);
-}
-
-/**
* Dump listing of tracked resources.
*
- * This function is very similar to memrec_dump_pointers() but is
- * intended for use with non-pointer data.
- *
- * @param memrec Address of the #spifmem_memrec_t we're dumping.
- *
* @see @link DOXGRP_MEM Memory Management Subsystem @endlink, MALLOC_DUMP(), libast_dump_mem_tables(),
- * memrec_dump_pointers()
+ * spifmem_dump_pointers()
* @ingroup DOXGRP_MEM
*/
void
-memrec_dump_resources(spifmem_memrec_t *memrec)
+spifmem_dump_resources(void)
{
register spifmem_ptr_t *p;
unsigned long i, total;
unsigned long len;
- ASSERT(memrec != NULL);
- len = memrec->cnt;
+ len = resource_rec.cnt;
fprintf(LIBAST_DEBUG_FD, "RES: %lu resources stored.\n",
- (unsigned long) memrec->cnt);
- fprintf(LIBAST_DEBUG_FD, "RES: Index | Resource ID | Filename | Line | Size \n");
- fprintf(LIBAST_DEBUG_FD, "RES: -------+-------------+----------------------+--------+--------\n");
+ (unsigned long) resource_rec.cnt);
+ fprintf(LIBAST_DEBUG_FD, "RES: Index | Resource ID | Filename | Line | Size | Type\n");
+ fprintf(LIBAST_DEBUG_FD, "RES: -------+-------------+----------------------+--------+--------+----------\n");
fflush(LIBAST_DEBUG_FD);
- for (p = memrec->ptrs, i = 0, total = 0; i < len; i++, p++) {
+ for (p = resource_rec.ptrs, i = 0, total = 0; i < len; i++, p++) {
total += p->size;
- fprintf(LIBAST_DEBUG_FD, "RES: %5lu | 0x%08lx | %20s | %6lu | %6lu\n",
- i, (unsigned long) p->ptr, NONULL(p->file),
- (unsigned long) p->line,
- (unsigned long) p->size);
+ fprintf(LIBAST_DEBUG_FD, "RES: %5lu | 0x%08lx | %20s | %6lu | %6lu | %-8s\n",
+ i, (unsigned long) p->ptr, NONULL(p->file), (unsigned long) p->line,
+ (unsigned long) p->size, p->type);
/* Flush after every line in case we crash */
fflush(LIBAST_DEBUG_FD);
}
@@ -384,468 +225,6 @@ memrec_dump_resources(spifmem_memrec_t *memrec)
fflush(LIBAST_DEBUG_FD);
}
-/******************** MEMORY ALLOCATION INTERFACE ********************/
-
-/**
- * LibAST implementation of malloc().
- *
- * When memory debugging is active (via #DEBUG_MEM), all calls to the
- * MALLOC() macro are routed here. The macro allows filename and line
- * number information to be provided thanks to the __FILE__ and
- * __LINE__ symbols pre-defined by cpp.
- *
- * @param filename The filename where the variable is being
- * allocated.
- * @param line The line number of @a filename where the variable
- * is being allocated.
- * @param size The requested size in bytes (as passed to MALLOC()).
- * @return A pointer to the newly-allocated memory.
- *
- * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, MALLOC()
- * @ingroup DOXGRP_MEM
- */
-void *
-spifmem_malloc(const char *filename, unsigned long line, size_t size)
-{
- void *temp;
-
-#if MALLOC_CALL_COUNT
- ++malloc_count;
- if (!(malloc_count % MALLOC_CALL_INTERVAL)) {
- fprintf(LIBAST_DEBUG_FD, "Calls to malloc(): %d\n", malloc_count);
- }
-#endif
-
- D_MEM(("%lu bytes requested at %s:%lu\n", size, NONULL(filename), line));
-
- temp = (void *) malloc(size);
- ASSERT_RVAL(!SPIF_PTR_ISNULL(temp), (spif_ptr_t) NULL);
- if (DEBUG_LEVEL >= DEBUG_MEM) {
- memrec_add_var(&malloc_rec, NONULL(filename), line, temp, size);
- }
- return (temp);
-}
-
-/**
- * LibAST implementation of realloc().
- *
- * When memory debugging is active (via #DEBUG_MEM), all calls to the
- * REALLOC() macro are routed here. The macro allows variable name,
- * filename, and line number information to be provided.
- *
- * @param var The variable name being resized.
- * @param filename The filename where the variable is being
- * reallocated.
- * @param line The line number of @a filename where the variable
- * is being reallocated.
- * @param ptr The old value of the pointer being resized.
- * @param size The new requested size in bytes (as passed to
- * REALLOC()).
- * @return The new value (possibly moved) of the pointer.
- *
- * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, REALLOC()
- * @ingroup DOXGRP_MEM
- */
-void *
-spifmem_realloc(const char *var, const char *filename, unsigned long line, void *ptr, size_t size)
-{
- void *temp;
-
-#if MALLOC_CALL_COUNT
- ++realloc_count;
- if (!(realloc_count % REALLOC_CALL_INTERVAL)) {
- D_MEM(("Calls to realloc(): %d\n", realloc_count));
- }
-#endif
-
- D_MEM(("Variable %s (%10p -> %lu) at %s:%lu\n", var, ptr, (unsigned long) size, NONULL(filename), line));
- if (!ptr) {
- temp = (void *) spifmem_malloc(filename, line, size);
- } else if (size == 0) {
- spifmem_free(var, filename, line, ptr);
- temp = NULL;
- } else {
- temp = (void *) realloc(ptr, size);
- ASSERT_RVAL(!SPIF_PTR_ISNULL(temp), (spif_ptr_t) NULL);
- if (DEBUG_LEVEL >= DEBUG_MEM) {
- memrec_chg_var(&malloc_rec, var, NONULL(filename), line, ptr, temp, size);
- }
- }
- return (temp);
-}
-
-/**
- * LibAST implementation of calloc().
- *
- * When memory debugging is active (via #DEBUG_MEM), all calls to the
- * CALLOC() macro are routed here. The macro allows filename and line
- * number information to be provided thanks to the __FILE__ and
- * __LINE__ symbols pre-defined by cpp.
- *
- * @param filename The filename where the variable is being
- * allocated.
- * @param line The line number of @a filename where the variable
- * is being allocated.
- * @param count The number of objects being allocated.
- * @param size The size in bytes of each object (as passed to
- * CALLOC()).
- * @return A pointer to the newly-allocated, zeroed memory.
- *
- * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, CALLOC()
- * @ingroup DOXGRP_MEM
- */
-void *
-spifmem_calloc(const char *filename, unsigned long line, size_t count, size_t size)
-{
- void *temp;
- size_t total_size;
-
- total_size = size * count;
-#if MALLOC_CALL_COUNT
- ++calloc_count;
- if (!(calloc_count % CALLOC_CALL_INTERVAL)) {
- fprintf(LIBAST_DEBUG_FD, "Calls to calloc(): %d\n", calloc_count);
- }
-#endif
-
- D_MEM(("%lu units of %lu bytes each (%lu bytes total) requested at %s:%lu\n",
- count, size, total_size, NONULL(filename), line));
- temp = (void *) calloc(count, size);
- ASSERT_RVAL(!SPIF_PTR_ISNULL(temp), (spif_ptr_t) NULL);
- if (DEBUG_LEVEL >= DEBUG_MEM) {
- memrec_add_var(&malloc_rec, NONULL(filename), line, temp, total_size);
- }
- return (temp);
-}
-
-/**
- * LibAST implementation of free().
- *
- * When memory debugging is active (via #DEBUG_MEM), all calls to the
- * FREE() macro are routed here. The macro allows variable name,
- * filename, and line number information to be provided.
- *
- * @param var The variable name being freed.
- * @param filename The filename where the variable is being freed.
- * @param line The line number of @a filename where the variable
- * is being freed.
- * @param ptr The pointer being freed (as passed to FREE()).
- *
- * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, FREE()
- * @ingroup DOXGRP_MEM
- */
-void
-spifmem_free(const char *var, const char *filename, unsigned long line, void *ptr)
-{
-#if MALLOC_CALL_COUNT
- ++free_count;
- if (!(free_count % FREE_CALL_INTERVAL)) {
- fprintf(LIBAST_DEBUG_FD, "Calls to free(): %d\n", free_count);
- }
-#endif
-
- D_MEM(("Variable %s (%10p) at %s:%lu\n", var, ptr, NONULL(filename), line));
- if (ptr) {
- if (DEBUG_LEVEL >= DEBUG_MEM) {
- memrec_rem_var(&malloc_rec, var, NONULL(filename), line, ptr);
- }
- free(ptr);
- } else {
- D_MEM(("ERROR: Caught attempt to free NULL pointer\n"));
- }
-}
-
-/**
- * LibAST implementation of strdup().
- *
- * When memory debugging is active (via #DEBUG_MEM), all calls to the
- * STRDUP() macro are routed here. The macro allows variable name,
- * filename, and line number information to be provided.
- *
- * @param var The variable name being duplicated.
- * @param filename The filename where the variable is being duplicated.
- * @param line The line number of @a filename where the variable
- * is being duplicated.
- * @param str The string being duplicated (as passed to STRDUP()).
- * @return A pointer to a newly-allocated copy of @a str.
- *
- * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, STRDUP()
- * @ingroup DOXGRP_MEM
- */
-char *
-spifmem_strdup(const char *var, const char *filename, unsigned long line, const char *str)
-{
- register char *newstr;
- register size_t len;
-
- ASSERT_RVAL(!SPIF_PTR_ISNULL(str), (char *) NULL);
- USE_VAR(var);
- D_MEM(("Variable %s (%10p) at %s:%lu\n", var, str, NONULL(filename), line));
-
- len = strlen((char *) str) + 1; /* Copy NUL byte also */
- newstr = (char *) spifmem_malloc(NONULL(filename), line, len);
- ASSERT_RVAL(!SPIF_PTR_ISNULL(newstr), (spif_ptr_t) NULL);
- strcpy((char *) newstr, (char *) str);
- return (newstr);
-}
-
-/**
- * Dump listing of tracked pointers.
- *
- * This function simply calls memrec_dump_pointers() and passes in the
- * address of the #malloc_rec variable.
- *
- * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, MALLOC_DUMP(), memrec_dump_pointers()
- * @ingroup DOXGRP_MEM
- */
-void
-spifmem_dump_mem_tables(void)
-{
- fprintf(LIBAST_DEBUG_FD, "Dumping memory allocation table:\n");
- memrec_dump_pointers(&malloc_rec);
-}
-
-#if LIBAST_X11_SUPPORT
-
-/******************** PIXMAP ALLOCATION INTERFACE ********************/
-
-/**
- * LibAST implementation of XCreatePixmap().
- *
- * When memory debugging is active (via #DEBUG_MEM), all calls to the
- * X_CREATE_PIXMAP() macro are routed here. The macro allows filename
- * and line number information to be provided thanks to the __FILE__
- * and __LINE__ symbols pre-defined by cpp.
- *
- * @param filename The filename where the pixmap is being created.
- * @param line The line number of @a filename where the pixmap is
- * being created.
- * @param d The Display for the new pixmap.
- * @param win The Drawable for the new pixmap.
- * @param w Width of the pixmap, in pixels.
- * @param h Height of the pixmap, in pixels.
- * @param depth The color depth for the new pixmap.
- * @return A newly-created Pixmap.
- *
- * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, X_CREATE_PIXMAP()
- * @ingroup DOXGRP_MEM
- */
-Pixmap
-spifmem_x_create_pixmap(const char *filename, unsigned long line, Display * d, Drawable win, unsigned int w, unsigned int h,
- unsigned int depth)
-{
- Pixmap p;
-
- p = XCreatePixmap(d, win, w, h, depth);
- D_MEM(("Created %ux%u pixmap 0x%08x of depth %u for window 0x%08x at %s:%lu\n", w, h, p, depth, win, NONULL(filename), line));
- ASSERT_RVAL(p != None, None);
- if (DEBUG_LEVEL >= DEBUG_MEM) {
- memrec_add_var(&pixmap_rec, NONULL(filename), line, (void *) p, w * h * (depth / 8));
- }
- return (p);
-}
-
-/**
- * LibAST implementation of XFreePixmap().
- *
- * When memory debugging is active (via #DEBUG_MEM), all calls to the
- * X_FREE_PIXMAP() macro are routed here. The macro allows variable
- * name, filename, and line number information to be provided.
- *
- * @param var The variable name of the pixmap being freed.
- * @param filename The filename where the pixmap is being freed.
- * @param line The line number of @a filename where the pixmap is
- * being freed.
- * @param d The Display for the pixmap.
- * @param p The Pixmap to be freed.
- *
- * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, X_FREE_PIXMAP()
- * @ingroup DOXGRP_MEM
- */
-void
-spifmem_x_free_pixmap(const char *var, const char *filename, unsigned long line, Display * d, Pixmap p)
-{
- D_MEM(("Freeing pixmap %s (0x%08x) at %s:%lu\n", var, p, NONULL(filename), line));
- if (p) {
- if (DEBUG_LEVEL >= DEBUG_MEM) {
- memrec_rem_var(&pixmap_rec, var, NONULL(filename), line, (void *) p);
- }
- XFreePixmap(d, p);
- } else {
- D_MEM(("ERROR: Caught attempt to free NULL pixmap\n"));
- }
-}
-
-# if LIBAST_IMLIB2_SUPPORT
-/**
- * Register a pixmap for tracking.
- *
- * Imlib has its own mechanism for creating pixmaps internally. In
- * order to keep track of these pixmaps, they must be registered with
- * LibAST using this function (via the IMLIB_REGISTER_PIXMAP() macro).
- *
- * @param var The variable name of the pixmap being registered.
- * @param filename The filename where the pixmap is being registered.
- * @param line The line number of @a filename where the pixmap is
- * being registered.
- * @param p The Pixmap being registered.
- *
- * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, IMLIB_REGISTER_PIXMAP()
- * @ingroup DOXGRP_MEM
- */
-void
-spifmem_imlib_register_pixmap(const char *var, const char *filename, unsigned long line, Pixmap p)
-{
- USE_VAR(var);
- D_MEM(("Registering pixmap %s (0x%08x) created by Imlib2 at %s:%lu\n", var, p, NONULL(filename), line));
- if (p) {
- if (DEBUG_LEVEL >= DEBUG_MEM) {
- if (!memrec_find_var(&pixmap_rec, (void *) p)) {
- memrec_add_var(&pixmap_rec, NONULL(filename), line, (void *) p, 1);
- } else {
- D_MEM(("Pixmap 0x%08x already registered.\n"));
- }
- }
- } else {
- D_MEM(("ERROR: Refusing to register a NULL pixmap\n"));
- }
-}
-
-/**
- * Free a pixmap created by Imlib.
- *
- * Imlib has its own mechanism for freeing pixmaps, and their
- * associated mask (if any), internally. All pixmaps created by Imlib
- * must also be freed by Imlib. It is safe, albeit a bit slower, to
- * free all pixmaps via Imlib, regardless of how they were created.
- *
- * @param var The variable name of the pixmap being freed.
- * @param filename The filename where the pixmap is being freed.
- * @param line The line number of @a filename where the pixmap is
- * being freed.
- * @param p The Pixmap being freed.
- *
- * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, IMLIB_FREE_PIXMAP()
- * @ingroup DOXGRP_MEM
- */
-void
-spifmem_imlib_free_pixmap(const char *var, const char *filename, unsigned long line, Pixmap p)
-{
- D_MEM(("Freeing pixmap %s (0x%08x) at %s:%lu using Imlib2\n", var, p, NONULL(filename), line));
- if (p) {
- if (DEBUG_LEVEL >= DEBUG_MEM) {
- memrec_rem_var(&pixmap_rec, var, NONULL(filename), line, (void *) p);
- }
- imlib_free_pixmap_and_mask(p);
- } else {
- D_MEM(("ERROR: Caught attempt to free NULL pixmap\n"));
- }
-}
-# endif
-
-/**
- * Dump listing of tracked pixmaps.
- *
- * This function simply calls memrec_dump_resources() and passes in
- * the address of the #pixmap_rec variable.
- *
- * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, PIXMAP_DUMP(), memrec_dump_resources()
- * @ingroup DOXGRP_MEM
- */
-void
-spifmem_dump_pixmap_tables(void)
-{
- fprintf(LIBAST_DEBUG_FD, "Dumping X11 Pixmap allocation table:\n");
- memrec_dump_resources(&pixmap_rec);
-}
-
-
-
-/********************** GC ALLOCATION INTERFACE **********************/
-
-/**
- * LibAST implementation of XCreateGC().
- *
- * When memory debugging is active (via #DEBUG_MEM), all calls to the
- * X_CREATE_GC() macro are routed here. The macro allows filename
- * and line number information to be provided thanks to the __FILE__
- * and __LINE__ symbols pre-defined by cpp.
- *
- * @param filename The filename where the GC is being created.
- * @param line The line number of @a filename where the GC is
- * being created.
- * @param d The Display for the new GC.
- * @param win The Drawable for the new GC.
- * @param mask Bitwise OR of zero or more GC flags.
- * @param gcv Pointer to XGCValues structure.
- * @return A newly-created GC.
- *
- * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, X_CREATE_GC()
- * @ingroup DOXGRP_MEM
- */
-GC
-spifmem_x_create_gc(const char *filename, unsigned long line, Display * d, Drawable win, unsigned long mask, XGCValues * gcv)
-{
- GC gc;
-
- D_MEM(("Creating gc for window 0x%08x at %s:%lu\n", win, NONULL(filename), line));
-
- gc = XCreateGC(d, win, mask, gcv);
- ASSERT_RVAL(gc != None, None);
- if (DEBUG_LEVEL >= DEBUG_MEM) {
- memrec_add_var(&gc_rec, NONULL(filename), line, (void *) gc, sizeof(XGCValues));
- }
- return (gc);
-}
-
-/**
- * LibAST implementation of XFreeGC().
- *
- * When memory debugging is active (via #DEBUG_MEM), all calls to the
- * X_FREE_GC() macro are routed here. The macro allows variable
- * name, filename, and line number information to be provided.
- *
- * @param var The variable name of the GC being freed.
- * @param filename The filename where the GC is being freed.
- * @param line The line number of @a filename where the GC is
- * being freed.
- * @param d The Display for the GC.
- * @param gc The GC to be freed.
- *
- * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, X_FREE_GC()
- * @ingroup DOXGRP_MEM
- */
-void
-spifmem_x_free_gc(const char *var, const char *filename, unsigned long line, Display * d, GC gc)
-{
- D_MEM(("spifmem_x_free_gc() called for variable %s (0x%08x) at %s:%lu\n", var, gc, NONULL(filename), line));
- if (gc) {
- if (DEBUG_LEVEL >= DEBUG_MEM) {
- memrec_rem_var(&gc_rec, var, NONULL(filename), line, (void *) gc);
- }
- XFreeGC(d, gc);
- } else {
- D_MEM(("ERROR: Caught attempt to free NULL GC\n"));
- }
-}
-
-/**
- * Dump listing of tracked GC's.
- *
- * This function simply calls memrec_dump_resources() and passes in
- * the address of the #gc_rec variable.
- *
- * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, GC_DUMP(), memrec_dump_resources()
- * @ingroup DOXGRP_MEM
- */
-void
-spifmem_dump_gc_tables(void)
-{
- fprintf(LIBAST_DEBUG_FD, "Dumping X11 GC allocation table:\n");
- memrec_dump_resources(&gc_rec);
-}
-#endif
-
/**
* Free an array of pointers.
*
@@ -886,27 +265,34 @@ spiftool_free_array(void *list, size_t count)
* This group of functions/defines/macros implements the memory
* management subsystem within LibAST.
*
- * LibAST provides a robust mechanism for tracking memory allocations
- * and deallocations. This system employs macro-based wrappers
- * around the standard libc malloc/realloc/calloc/free routines, other
- * libc fare such as strdup(), Xlib GC and Pixmap create/free
- * routines, and even Imlib2's own pixmap functions.
+ * LibAST provides a mechanism for tracking resource allocations and
+ * deallocations. This system employs macro-based wrappers around
+ * various resource allocators/deallocators such as Xlib GC and Pixmap
+ * create/free routines and Imlib2 pixmap functions.
*
* To take advantage of this system, simply substitute the macro
* versions in place of the standard versions throughout your code
- * (e.g., use MALLOC() instead of malloc(), X_FREE_GC() instead of
- * XFreeGC(), etc.). If DEBUG is set to a value higher than
- * DEBUG_MEM, the LibAST-custom versions of these functions will be
- * used. Of course, if memory debugging has not been requested, the
- * original libc/XLib/Imlib2 versions will be used instead, so that
- * you only incur the debugging overhead when you want it.
- *
- * LibAST has also been designed to work effectively with Gray
- * Watson's excellent malloc-debugging library, dmalloc
- * (http://dmalloc.com/), either instead of or in addition to its own
- * memory tracking routines. Unlike LibAST, dmalloc supplements
- * memory allocation tracking with fence-post checking, freed pointer
- * reuse detection, and other very handy features.
+ * (e.g., X_FREE_GC() instead of XFreeGC()). If DEBUG is set to a
+ * value higher than DEBUG_MEM, the LibAST-custom versions of these
+ * functions will be used. Of course, if memory debugging has not
+ * been requested, the original libc/XLib/Imlib2 versions will be used
+ * instead, so that you only incur the debugging overhead when you
+ * want it.
+ *
+ * You can also define your own macros to wrap allocators and
+ * deallocators if LibAST doesn't already contain support for the
+ * resources you wish to track. Simply call spifmem_add_var(),
+ * spifmem_chg_var(), and spifmem_rem_var() whenever the resource is
+ * created, resized, or deleted (respectively).
+ *
+ * NOTE: If your compiler does not support compound statement
+ * expressions (i.e., a code block whose final statement specifies the
+ * value of a parenthesized expression, such as:
+ * ({int a = 1, b = 2; a *= b; b += a; a+b;})),
+ * LibAST's built-in wrapper macros will not be available to you, nor
+ * are you likely to be able to wrap many allocator functions with
+ * your own macros. In these situations, you'll need to call the
+ * LibAST memory routines separately.
*
* A small sample program demonstrating use of LibAST's memory
* management system can be found
@@ -927,20 +313,20 @@ spiftool_free_array(void *list, size_t count)
* @code
* $ ./mem_example
* [1045859036] mem.c | 246: spifmem_malloc(): 500 bytes requested at mem_example.c:27
- * [1045859036] mem.c | 74: memrec_add_var(): Adding variable (0x8049a20, 500 bytes) from mem_example.c:27.
- * [1045859036] mem.c | 75: memrec_add_var(): Storing as pointer #1 at 0x8049c18 (from 0x8049c18).
+ * [1045859036] mem.c | 74: spifmem_add_var(): Adding variable (0x8049a20, 500 bytes) from mem_example.c:27.
+ * [1045859036] mem.c | 75: spifmem_add_var(): Storing as pointer #1 at 0x8049c18 (from 0x8049c18).
* [1045859036] mem.c | 329: spifmem_strdup(): Variable pointer (0x8049a20) at mem_example.c:36
* [1045859036] mem.c | 246: spifmem_malloc(): 16 bytes requested at mem_example.c:36
- * [1045859036] mem.c | 74: memrec_add_var(): Adding variable (0x8049c40, 16 bytes) from mem_example.c:36.
- * [1045859036] mem.c | 75: memrec_add_var(): Storing as pointer #2 at 0x8049c7c (from 0x8049c58).
+ * [1045859036] mem.c | 74: spifmem_add_var(): Adding variable (0x8049c40, 16 bytes) from mem_example.c:36.
+ * [1045859036] mem.c | 75: spifmem_add_var(): Storing as pointer #2 at 0x8049c7c (from 0x8049c58).
* [1045859036] mem.c | 312: spifmem_free(): Variable dup (0x8049c40) at mem_example.c:39
- * [1045859036] mem.c | 94: memrec_find_var(): Found pointer #2 stored at 0x8049c7c (from 0x8049c58)
- * [1045859036] mem.c | 113: memrec_rem_var(): Removing variable dup (0x8049c40) of size 16
+ * [1045859036] mem.c | 94: spifmem_find_var(): Found pointer #2 stored at 0x8049c7c (from 0x8049c58)
+ * [1045859036] mem.c | 113: spifmem_rem_var(): Removing variable dup (0x8049c40) of size 16
* [1045859036] mem.c | 312: spifmem_free(): Variable dup ( (nil)) at mem_example.c:43
* [1045859036] mem.c | 319: spifmem_free(): ERROR: Caught attempt to free NULL pointer
* [1045859036] mem.c | 268: spifmem_realloc(): Variable pointer (0x8049a20 -> 1000) at mem_example.c:46
- * [1045859036] mem.c | 94: memrec_find_var(): Found pointer #1 stored at 0x8049c58 (from 0x8049c58)
- * [1045859036] mem.c | 132: memrec_chg_var(): Changing variable pointer (0x8049a20, 500 -> 0x8049c80, 1000)
+ * [1045859036] mem.c | 94: spifmem_find_var(): Found pointer #1 stored at 0x8049c58 (from 0x8049c58)
+ * [1045859036] mem.c | 132: spifmem_chg_var(): Changing variable pointer (0x8049a20, 500 -> 0x8049c80, 1000)
* Dumping memory allocation table:
* PTR: 1 pointers stored.
* PTR: Pointer | Filename | Line | Address | Size | Offset | 00 01 02 03 04 05 06 07 | ASCII