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)
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([
87 AC_MSG_RESULT([no - assumed because cross-compiling]) 87 AC_MSG_RESULT([no - assumed because cross-compiling])
88]) 88])
89 89
90AST_X11_SUPPORT()
91AST_IMLIB2_SUPPORT()
92AST_MMX_SUPPORT() 90AST_MMX_SUPPORT()
93AST_ARG_REGEXP(REGEXP) 91AST_ARG_REGEXP(REGEXP)
94AST_ARG_BACKQUOTE_EXEC(ALLOW_BACKQUOTE_EXEC) 92AST_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();
967 967
968/********************************* MEM GOOP ***********************************/ 968/********************************* MEM GOOP ***********************************/
969/** 969/**
970 * @def MALLOC(sz)
971 * Allocate @a sz bytes of memory.
972 *
973 * This macro is a replacement for the libc function malloc(). It
974 * allocates the specified number of bytes of memory on the heap and
975 * returns a pointer to that memory location. This macro calls libc's
976 * malloc() if memory debugging is off, and spifmem_malloc() if it's
977 * on.
978 *
979 * @param sz The size in bytes of the block of memory to allocate.
980 * @return A pointer to the allocated memory.
981 * @see @link DOXGRP_MEM Memory Management Subsystem @endlink
982 * @ingroup DOXGRP_MEM
983 */
984/**
985 * @def CALLOC(type, n)
986 * Allocate enough memory for @a n objects of type @a type.
987 *
988 * This macro is a replacement for the libc function calloc(). It
989 * allocates a block of memory on the heap large enough to hold @a n
990 * objects of type @a type (e.g., a @a type array of size @a n). The
991 * memory area is zeroed out prior to the pointer to it being
992 * returned. This macro calls libc's calloc() if memory debugging is
993 * off and spifmem_calloc() if it's on.
994 *
995 * @param type The type of object to be allocated (e.g., int).
996 * @param n The number of objects to be allocated.
997 * @return A pointer to the allocated memory.
998 * @see @link DOXGRP_MEM Memory Management Subsystem @endlink
999 * @ingroup DOXGRP_MEM
1000 */
1001/**
1002 * @def REALLOC(mem, sz)
1003 * Resize the memory block pointed to by @a mem to @a sz bytes.
1004 *
1005 * This macro is a replacement for the libc function realloc(). It
1006 * changes the size of a chunk of memory previously allocated by
1007 * malloc() or calloc() (or, by extension, the MALLOC()/CALLOC()
1008 * macros) and returns a pointer to the (possibly moved) memory area.
1009 * This macro calls libc's realloc() if memory debugging is off and
1010 * spifmem_realloc() if it's on.
1011 *
1012 * @param mem The old pointer whose size will be changed.
1013 * @param sz The new size, in bytes, to be allocated.
1014 * @return The new pointer value, which may or may not differ from the
1015 * old value.
1016 * @see @link DOXGRP_MEM Memory Management Subsystem @endlink
1017 * @ingroup DOXGRP_MEM
1018 */
1019/**
1020 * @def FREE(ptr)
1021 * Free a previously-allocated memory block.
1022 *
1023 * This macro is a replacement for the libc function free(). It
1024 * returns the previously-allocated memory block pointed to by @a ptr
1025 * to the heap. This macro calls libc's free() if memory debugging is
1026 * off and spifmem_free() if it's on. The @a ptr parameter is assigned
1027 * the value of NULL after it has been freed.
1028 *
1029 * @param ptr The pointer to be freed.
1030 * @see @link DOXGRP_MEM Memory Management Subsystem @endlink
1031 * @ingroup DOXGRP_MEM
1032 */
1033/**
1034 * @def ALLOCA(sz)
1035 * Allocate @a sz bytes of memory on the stack.
1036 *
1037 * This macro is a replacement for the libc function alloca(). It
1038 * allocates the specified number of bytes of memory on the stack and
1039 * returns a pointer to that memory location. This macro calls libc's
1040 * alloca() if memory debugging is off, and wraps it if it's
1041 * on.
1042 *
1043 * @param sz The size in bytes of the block of memory to allocate.
1044 * @return A pointer to the allocated memory.
1045 * @see @link DOXGRP_MEM Memory Management Subsystem @endlink
1046 * @ingroup DOXGRP_MEM
1047 */
1048/**
1049 * @def STRDUP(s)
1050 * Duplicate a string pointer and return a pointer to the new copy.
1051 *
1052 * This macro is a replacement for the libc function strdup(). It
1053 * allocates a section of memory large enough to hold the string @a s
1054 * (including the trailing NUL character), copies the contents of @a s
1055 * into the new buffer, and returns a pointer to the new copy. This
1056 * macro calls libc's strdup() of memory debugging is off and
1057 * spifmem_strdup() if it's on.
1058 *
1059 * @param s The string to duplicate.
1060 * @return A pointer to the newly-created copy.
1061 * @see @link DOXGRP_MEM Memory Management Subsystem @endlink
1062 * @ingroup DOXGRP_MEM
1063 */
1064/**
1065 * @def MALLOC_DUMP()
1066 * Dumps a listing of all allocated pointers along with their sizes
1067 * and contents in both hex and ASCII.
1068 *
1069 * This macro is used to view the status of memory allocated via the
1070 * LibAST memory management system. First the pointers used to track
1071 * allocated memory are dumped (that's what pointer #0 is); then, each
1072 * allocated pointer is dumped along with its size and contents, the
1073 * latter being displayed both in hexadecimal form and ASCII form.
1074 * Non-printable characters are replaced by dots ('.'). You can see
1075 * a sample of the output in the
1076 * @link mem_example.c memory management system example @endlink.
1077 *
1078 * @see @link DOXGRP_MEM Memory Management Subsystem @endlink
1079 * @ingroup DOXGRP_MEM
1080 */
1081/**
1082 * @def X_CREATE_PIXMAP(d, win, w, h, depth) 970 * @def X_CREATE_PIXMAP(d, win, w, h, depth)
1083 * Create an X pixmap. 971 * Create an X pixmap.
1084 * 972 *
@@ -1194,119 +1082,79 @@ extern int re_exec();
1194 * @see @link DOXGRP_MEM Memory Management Subsystem @endlink 1082 * @see @link DOXGRP_MEM Memory Management Subsystem @endlink
1195 * @ingroup DOXGRP_MEM 1083 * @ingroup DOXGRP_MEM
1196 */ 1084 */
1197/**
1198 * @def MALLOC_CALL_INTERVAL
1199 * MALLOC() call count interval.
1200 *
1201 * LibAST has the ability to count calls to MALLOC(); this defines the
1202 * interval for reporting the call count. The default is 25, meaning
1203 * that LibAST will print the current count every 25 calls. Note that
1204 * MALLOC_CALL_COUNT must be defined when compiling LibAST, in
1205 * addition to memory debugging, for this feature to work.
1206 *
1207 * @see @link DOXGRP_MEM Memory Management Subsystem @endlink
1208 * @ingroup DOXGRP_MEM
1209 */
1210/**
1211 * @def REALLOC_CALL_INTERVAL
1212 * REALLOC() call count interval.
1213 *
1214 * LibAST has the ability to count calls to REALLOC(); this defines
1215 * the interval for reporting the call count. The default is 25,
1216 * meaning that LibAST will print the current count every 25 calls.
1217 * Note that MALLOC_CALL_COUNT must be defined when compiling LibAST,
1218 * in addition to memory debugging, for this feature to work.
1219 *
1220 * @see @link DOXGRP_MEM Memory Management Subsystem @endlink
1221 * @ingroup DOXGRP_MEM
1222 */
1223/**
1224 * @def CALLOC_CALL_INTERVAL
1225 * CALLOC() call count interval.
1226 *
1227 * LibAST has the ability to count calls to CALLOC(); this defines the
1228 * interval for reporting the call count. The default is 25, meaning
1229 * that LibAST will print the current count every 25 calls. Note that
1230 * MALLOC_CALL_COUNT must be defined when compiling LibAST, in
1231 * addition to memory debugging, for this feature to work.
1232 *
1233 * @see @link DOXGRP_MEM Memory Management Subsystem @endlink
1234 * @ingroup DOXGRP_MEM
1235 */
1236/**
1237 * @def FREE_CALL_INTERVAL
1238 * FREE() call count interval.
1239 *
1240 * LibAST has the ability to count calls to FREE(); this defines the
1241 * interval for reporting the call count. The default is 25, meaning
1242 * that LibAST will print the current count every 25 calls. Note that
1243 * MALLOC_CALL_COUNT must be defined when compiling LibAST, in
1244 * addition to memory debugging, for this feature to work.
1245 *
1246 * @see @link DOXGRP_MEM Memory Management Subsystem @endlink
1247 * @ingroup DOXGRP_MEM
1248 */
1249#if (DEBUG >= DEBUG_MEM) 1085#if (DEBUG >= DEBUG_MEM)
1250# define MALLOC(sz) spifmem_malloc(__FILE__, __LINE__, (sz))
1251# define CALLOC(type,n) spifmem_calloc(__FILE__, __LINE__, (n), (sizeof(type)))
1252# define REALLOC(mem,sz) spifmem_realloc(#mem, __FILE__, __LINE__, (mem), (sz))
1253# define FREE(ptr) do { spifmem_free(#ptr, __FILE__, __LINE__, (ptr)); (ptr) = NULL; } while (0)
1254# ifdef LIBAST_SUPPORT_MACRO_CSE 1086# ifdef LIBAST_SUPPORT_MACRO_CSE
1255# define ALLOCA(sz) ({ void *p = alloca(sz); p; })
1256# else
1257# define ALLOCA(sz) alloca(sz)
1258# endif
1259# define STRDUP(s) spifmem_strdup(#s, __FILE__, __LINE__, (s))
1260# define MALLOC_DUMP() spifmem_dump_mem_tables()
1261 1087
1262/* X11 Wrappers */ 1088/* X11 Wrappers */
1263# if 0 && defined(LIBAST_SUPPORT_MACRO_CSE)
1264# define X_CREATE_PIXMAP(d, win, w, h, depth) ({ \ 1089# define X_CREATE_PIXMAP(d, win, w, h, depth) ({ \
1265 Pixmap p = XCreatePixmap((d), (win), (w), (h), (depth)); \ 1090 Pixmap p = XCreatePixmap((d), (win), (w), (h), (depth)); \
1266 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__)); \ 1091 D_MEM(("Created %ux%u pixmap 0x%08x of depth %u for window 0x%08x at %s:%lu\n", \
1267 if (p == None) return p; \ 1092 (w), (h), p, (depth), (win), __FILE__, __LINE__)); \
1268 memrec_add_var(&pixmap_rec, (spif_charptr_t) NONULL(filename), line, (void *) p, w * h * (depth / 8)); \ 1093 if (p && (DEBUG_LEVEL >= DEBUG_MEM)) spifmem_add_var(__FILE__, __LINE__, (void *) p, w * h * (depth / 8), "X Pixmap"); \
1269 p; \ 1094 p; \
1270 }) 1095 })
1271# endif 1096# define X_FREE_PIXMAP(d, p) do { \
1272# define X_CREATE_PIXMAP(d, win, w, h, depth) spifmem_x_create_pixmap(__FILE__, __LINE__, (d), (win), (w), (h), (depth)) 1097 D_MEM(("Freeing pixmap %s (0x%08x) at %s:%lu\n", #p, p, __FILE__, __LINE__)); \
1273# define X_FREE_PIXMAP(d, p) spifmem_x_free_pixmap(#p, __FILE__, __LINE__, (d), (p)) 1098 if (p) { \
1274# if LIBAST_IMLIB2_SUPPORT 1099 if (DEBUG_LEVEL >= DEBUG_MEM) spifmem_rem_var(#p, __FILE__, __LINE__, (p)); \
1275# define IMLIB_REGISTER_PIXMAP(p) spifmem_imlib_register_pixmap(#p, __FILE__, __LINE__, (p)) 1100 XFreePixmap((d), (p)); \
1276# define IMLIB_FREE_PIXMAP(p) spifmem_imlib_free_pixmap(#p, __FILE__, __LINE__, (p)) 1101 } else { \
1277# else 1102 D_MEM(("ERROR: Caught attempt to free NULL pixmap\n")); \
1278# define IMLIB_REGISTER_PIXMAP(p) NOP 1103 } \
1279# define IMLIB_FREE_PIXMAP(p) NOP 1104 } while (0)
1280# endif 1105# define X_CREATE_GC(d, win, f, gcv) ({ \
1281# define PIXMAP_DUMP() spifmem_dump_pixmap_tables() 1106 GC gc = XCreateGC((d), (win), (mask), (gcv)); \
1282# define X_CREATE_GC(d, win, f, gcv) spifmem_x_create_gc(__FILE__, __LINE__, (d), (win), (f), (gcv)) 1107 D_MEM(("Created gc 0x%08x for window 0x%08x at %s:%lu\n", (int) gc, (win), __FILE__, __LINE__)); \
1283# define X_FREE_GC(d, gc) spifmem_x_free_gc(#gc, __FILE__, __LINE__, (d), (gc)) 1108 if (gc && (DEBUG_LEVEL >= DEBUG_MEM)) spifmem_add_var(__FILE__, __LINE__, (void *) gc, sizeof(XGCValues), "X GC"); \
1284# define GC_DUMP() spifmem_dump_gc_tables() 1109 gc; \
1285# define MALLOC_CALL_INTERVAL 25 1110 })
1286# define REALLOC_CALL_INTERVAL 25 1111# define X_FREE_GC(d, gc) do { \
1287# define CALLOC_CALL_INTERVAL 25 1112 D_MEM(("Freeing GC %s (0x%08x) at %s:%lu\n", #gc, gc, __FILE__, __LINE__)); \
1288# define FREE_CALL_INTERVAL 25 1113 if (gc) { \
1114 if (DEBUG_LEVEL >= DEBUG_MEM) spifmem_rem_var(#gc, __FILE__, __LINE__, (gc)); \
1115 XFreeGC((d), (gc)); \
1116 } else { \
1117 D_MEM(("ERROR: Caught attempt to free NULL GC\n")); \
1118 } \
1119 } while (0)
1120# else /* LIBAST_SUPPORT_MACRO_CSE */
1121# define X_CREATE_PIXMAP(d, win, w, h, depth) XCreatePixmap((d), (win), (w), (h), (depth))
1122# define X_FREE_PIXMAP(d, p) XFreePixmap((d), (p))
1123# define X_CREATE_GC(d, win, f, gcv) XCreateGC((d), (win), (f), (gcv))
1124# define X_FREE_GC(d, gc) XFreeGC((d), (gc))
1125# endif /* LIBAST_SUPPORT_MACRO_CSE */
1126# define IMLIB_REGISTER_PIXMAP(p) do { \
1127 D_MEM(("Registering pixmap %s (0x%08x) created by Imlib2 at %s:%lu\n", #p, p, __FILE__, __LINE__)); \
1128 if (p) { \
1129 if (DEBUG_LEVEL >= DEBUG_MEM) { \
1130 if (!spifmem_find_var((void *) p)) { \
1131 spifmem_add_var(__FILE__, __LINE__, (void *) p, 1, "Imlib2 Pixmap"); \
1132 } else { \
1133 D_MEM(("Pixmap 0x%08x already registered.\n", p)); \
1134 } \
1135 } \
1136 } else { \
1137 D_MEM(("ERROR: Refusing to register a NULL pixmap\n")); \
1138 } \
1139 } while (0)
1140# define IMLIB_FREE_PIXMAP(p) do { \
1141 D_MEM(("Freeing pixmap %s (0x%08x) at %s:%lu using Imlib2\n", #p, p, __FILE__, __LINE__)); \
1142 if (p) { \
1143 if (DEBUG_LEVEL >= DEBUG_MEM) spifmem_rem_var(#p, __FILE__, __LINE__, (p)); \
1144 imlib_free_pixmap_and_mask(p); \
1145 } else { \
1146 D_MEM(("ERROR: Caught attempt to free NULL pixmap\n")); \
1147 } \
1148 } while (0)
1149# define SPIFMEM_DUMP() spifmem_dump_resources()
1289#else 1150#else
1290# define MALLOC(sz) malloc(sz)
1291# define CALLOC(type,n) calloc((n),(sizeof(type)))
1292# define REALLOC(mem,sz) ((sz) ? ((mem) ? (realloc((mem), (sz))) : (malloc(sz))) : ((mem) ? (free(mem), NULL) : (NULL)))
1293# define FREE(ptr) do { free(ptr); (ptr) = NULL; } while (0)
1294# define ALLOCA(sz) alloca(sz)
1295# define STRDUP(s) strdup((char *) s)
1296# define MALLOC_DUMP() NOP
1297# define X_CREATE_PIXMAP(d, win, w, h, depth) XCreatePixmap((d), (win), (w), (h), (depth)) 1151# define X_CREATE_PIXMAP(d, win, w, h, depth) XCreatePixmap((d), (win), (w), (h), (depth))
1298# define X_FREE_PIXMAP(d, p) XFreePixmap((d), (p)) 1152# define X_FREE_PIXMAP(d, p) XFreePixmap((d), (p))
1299# ifdef LIBAST_IMLIB2_SUPPORT
1300# define IMLIB_REGISTER_PIXMAP(p) NOP
1301# define IMLIB_FREE_PIXMAP(p) imlib_free_pixmap_and_mask(p)
1302# else
1303# define IMLIB_REGISTER_PIXMAP(p) NOP
1304# define IMLIB_FREE_PIXMAP(p) NOP
1305# endif
1306# define PIXMAP_DUMP() NOP
1307# define X_CREATE_GC(d, win, f, gcv) XCreateGC((d), (win), (f), (gcv)) 1153# define X_CREATE_GC(d, win, f, gcv) XCreateGC((d), (win), (f), (gcv))
1308# define X_FREE_GC(d, gc) XFreeGC((d), (gc)) 1154# define X_FREE_GC(d, gc) XFreeGC((d), (gc))
1309# define GC_DUMP() NOP 1155# define IMLIB_REGISTER_PIXMAP(p) NOP
1156# define IMLIB_FREE_PIXMAP(p) imlib_free_pixmap_and_mask(p)
1157# define SPIFMEM_DUMP() NOP
1310#endif 1158#endif
1311 1159
1312/** 1160/**
@@ -1329,7 +1177,6 @@ extern int re_exec();
1329 * track of what pointers have been allocated, where they were 1177 * track of what pointers have been allocated, where they were
1330 * allocated, and how much space was requested. 1178 * allocated, and how much space was requested.
1331 * 1179 *
1332 * @see MALLOC(), REALLOC(), CALLOC(), FREE()
1333 * @ingroup DOXGRP_MEM 1180 * @ingroup DOXGRP_MEM
1334 */ 1181 */
1335typedef struct spifmem_ptr_t { 1182typedef struct spifmem_ptr_t {
@@ -1337,6 +1184,8 @@ typedef struct spifmem_ptr_t {
1337 void *ptr; 1184 void *ptr;
1338 /** The pointer's size, in bytes. The pointer's size, in bytes. */ 1185 /** The pointer's size, in bytes. The pointer's size, in bytes. */
1339 size_t size; 1186 size_t size;
1187 /** The resource type. The resource type. */
1188 char *type;
1340 /** Filename. The file which last (re)allocated the pointer. */ 1189 /** Filename. The file which last (re)allocated the pointer. */
1341 spif_char_t file[SPIFMEM_FNAME_LEN + 1]; 1190 spif_char_t file[SPIFMEM_FNAME_LEN + 1];
1342 /** Line number. The line number where the pointer was last (re)allocated. */ 1191 /** Line number. The line number where the pointer was last (re)allocated. */
@@ -2837,30 +2686,11 @@ extern unsigned int DEBUG_LEVEL;
2837 2686
2838/* mem.c */ 2687/* mem.c */
2839extern void spifmem_init(void); 2688extern void spifmem_init(void);
2840extern void memrec_add_var(spifmem_memrec_t *, const char *, unsigned long, void *, size_t); 2689extern void spifmem_add_var(const char *, unsigned long, void *, size_t, char *);
2841extern spifmem_ptr_t *memrec_find_var(spifmem_memrec_t *, const void *); 2690extern spifmem_ptr_t *spifmem_find_var(const void *);
2842extern void memrec_rem_var(spifmem_memrec_t *, const char *, const char *, unsigned long, const void *); 2691extern void spifmem_rem_var(const char *, const char *, unsigned long, const void *);
2843extern void memrec_chg_var(spifmem_memrec_t *, const char *, const char *, unsigned long, const void *, void *, size_t); 2692extern void spifmem_chg_var(const char *, const char *, unsigned long, const void *, void *, size_t);
2844extern void memrec_dump_pointers(spifmem_memrec_t *); 2693extern void spifmem_dump_resources(void);
2845extern void memrec_dump_resources(spifmem_memrec_t *);
2846extern void *spifmem_malloc(const char *, unsigned long, size_t);
2847extern void *spifmem_realloc(const char *, const char *, unsigned long, void *, size_t);
2848extern void *spifmem_calloc(const char *, unsigned long, size_t, size_t);
2849extern void spifmem_free(const char *, const char *, unsigned long, void *);
2850extern char *spifmem_strdup(const char *, const char *, unsigned long, const char *);
2851extern void spifmem_dump_mem_tables(void);
2852#if LIBAST_X11_SUPPORT
2853extern Pixmap spifmem_x_create_pixmap(const char *, unsigned long, Display *, Drawable, unsigned int, unsigned int, unsigned int);
2854extern void spifmem_x_free_pixmap(const char *, const char *, unsigned long, Display *, Pixmap);
2855# if LIBAST_IMLIB2_SUPPORT
2856extern void spifmem_imlib_register_pixmap(const char * var, const char * filename, unsigned long line, Pixmap p);
2857extern void spifmem_imlib_free_pixmap(const char * var, const char * filename, unsigned long line, Pixmap p);
2858# endif
2859extern void spifmem_dump_pixmap_tables(void);
2860extern GC spifmem_x_create_gc(const char *, unsigned long, Display *, Drawable, unsigned long, XGCValues *);
2861extern void spifmem_x_free_gc(const char *, const char *, unsigned long, Display *, GC);
2862extern void spifmem_dump_gc_tables(void);
2863#endif
2864extern void spiftool_free_array(void *, size_t); 2694extern void spiftool_free_array(void *, size_t);
2865 2695
2866/* file.c */ 2696/* file.c */
@@ -3016,4 +2846,15 @@ static void (*fatal_error)(const char *, ...) = libast_fatal_error;
3016 2846
3017#endif /* LIBAST_COMPAT_05_API */ 2847#endif /* LIBAST_COMPAT_05_API */
3018 2848
2849#if LIBAST_COMPAT_07_API
2850# define MALLOC(sz) malloc(sz)
2851# define CALLOC(type,n) calloc((n),(sizeof(type)))
2852# define REALLOC(mem,sz) ((sz) ? ((mem) ? (realloc((mem), (sz))) : (malloc(sz))) : ((mem) ? (free(mem), NULL) : (NULL)))
2853# define FREE(ptr) do { free(ptr); (ptr) = NULL; } while (0)
2854# define STRDUP(s) strdup((char *) s)
2855# define MALLOC_DUMP() NOP
2856# define PIXMAP_DUMP() SPIFMEM_DUMP()
2857# define GC_DUMP() SPIFMEM_DUMP()
2858#endif /* LIBAST_COMPAT_07_API */
2859
3019#endif /* _LIBAST_H_ */ 2860#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 @@
96# define LIBAST_COMPAT_05_API 0 96# define LIBAST_COMPAT_05_API 0
97#endif 97#endif
98 98
99/* App-definable; requests 0.7 API compatibility. */
100#ifndef LIBAST_COMPAT_07_API
101# define LIBAST_COMPAT_07_API 0
102#endif
103
99/* A bunch of security checks. */ 104/* A bunch of security checks. */
100#ifndef HAVE_RLIMIT_MEMLOCK 105#ifndef HAVE_RLIMIT_MEMLOCK
101# define HAVE_RLIMIT_MEMLOCK 0 106# 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#
179dnl# LibAST macro for X11 support 179dnl# LibAST macro for X11 support
180dnl# 180dnl#
181AC_DEFUN([AST_X11_SUPPORT], [ 181AC_DEFUN([AST_X11_SUPPORT], [
182 AC_PATH_XTRA 182 :
183 if test ! -z "$X_CFLAGS"; then
184 if test -z "$CPPFLAGS"; then
185 CPPFLAGS="$X_CFLAGS"
186 else
187 CPPFLAGS="$CPPFLAGS $X_CFLAGS"
188 fi
189 fi
190 if test ! -z "$X_LIBS"; then
191 if test -z "$LDFLAGS"; then
192 LDFLAGS="$X_LIBS"
193 else
194 LDFLAGS="$LDFLAGS $X_LIBS"
195 fi
196 fi
197 LIBAST_X11_SUPPORT=""
198 if test "x$no_x" != "xyes"; then
199 AC_CHECK_LIB(X11, XOpenDisplay, [
200 LIBAST_X11_SUPPORT="X11"
201 GRLIBS="-lX11"
202 AC_DEFINE([LIBAST_X11_SUPPORT], [1], [Define for X11 support.])
203 ])
204 fi
205 AC_SUBST(LIBAST_X11_SUPPORT)
206]) 183])
207 184
208dnl# 185dnl#
209dnl# LibAST macro for Imlib2 support 186dnl# LibAST macro for Imlib2 support
210dnl# 187dnl#
211AC_DEFUN([AST_IMLIB2_SUPPORT], [ 188AC_DEFUN([AST_IMLIB2_SUPPORT], [
212 AC_ARG_WITH(imlib, 189 :
213 [ --with-imlib[=DIR] compile with Imlib2 support (default)],
214 [
215 if test "$withval" != "no"; then
216 if test "$withval" != "yes"; then
217 CPPFLAGS="$CPPFLAGS -I${withval}/include"
218 LDFLAGS="$LDFLAGS -L${withval}/lib"
219 fi
220 USE_IMLIB=1
221 else
222 USE_IMLIB=0
223 fi
224 ], [
225 USE_IMLIB=1
226 ])
227 LIBAST_IMLIB2_SUPPORT=""
228 if test $USE_IMLIB -eq 1 ; then
229 AC_CHECK_PROG(IMLIB2_CONFIG, imlib2-config, imlib2-config)
230 if test "x$IMLIB2_CONFIG" != "x"; then
231 GRLIBS="`$IMLIB2_CONFIG --libs`"
232 CFLAGS="$CFLAGS `$IMLIB2_CONFIG --cflags`"
233 AC_DEFINE([LIBAST_IMLIB2_SUPPORT], [1], [Define for Imlib2 support.])
234 LIBAST_IMLIB2_SUPPORT="Imlib2"
235 else
236 AC_CHECK_LIB(m, pow, LIBS="-lm $LIBS")
237 AC_CHECK_LIB(dl, dlopen, LIBS="-ldl $LIBS")
238 AC_CHECK_LIB(freetype, FT_Init_FreeType, GRLIBS="-lfreetype $GRLIBS", , $GRLIBS)
239 AC_CHECK_LIB(Imlib2, imlib_create_image, [
240 GRLIBS="-lImlib2 $GRLIBS"
241 AC_DEFINE([LIBAST_IMLIB2_SUPPORT], [1], [Define for Imlib2 support.])
242 LIBAST_IMLIB2_SUPPORT="Imlib2"
243 ], [
244 AC_WARN(*** Imlib2 support has been disabled because Imlib2 ***)
245 AC_WARN(*** was not found or could not be linked. ***)
246 ], $GRLIBS)
247 fi
248 fi
249 AC_SUBST(LIBAST_IMLIB2_SUPPORT)
250]) 190])
251 191
252dnl# 192dnl#
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 \
11obj.c objpair.c options.c pthreads.c regexp.c socket.c str.c strings.c \ 11obj.c objpair.c options.c pthreads.c regexp.c socket.c str.c strings.c \
12snprintf.c tok.c url.c ustr.c 12snprintf.c tok.c url.c ustr.c
13 13
14libast_la_LDFLAGS = -version-info 2:2:0 14libast_la_LDFLAGS = -version-info 3:0:0
15MAINTAINERCLEANFILES = Makefile.in 15MAINTAINERCLEANFILES = 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 @@
36 36
37#include "libast_internal.h" 37#include "libast_internal.h"
38 38
39#if MALLOC_CALL_COUNT
40/*@{*/
41/** 39/**
42 * @name Memory Management Call Tracking 40 * Allocated resources.
43 * Count calls to memory management functions.
44 * 41 *
45 * This group of variables is used to count calls to the memory 42 * This structure keeps track of generic resources.
46 * management functions. Call counting is controlled by the
47 * #MALLOC_CALL_COUNT symbol, and is off by default.
48 *
49 * @see @link DOXGRP_MEM Memory Management Subsystem @endlink
50 * @ingroup DOXGRP_MEM
51 */
52
53/** Count calls to MALLOC(). Count calls to MALLOC(). */
54static int malloc_count = 0;
55/** Count calls to CALLOC(). Count calls to CALLOC(). */
56static int calloc_count = 0;
57/** Count calls to REALLOC(). Count calls to REALLOC(). */
58static int realloc_count = 0;
59/** Count calls to FREE(). Count calls to FREE(). */
60static int free_count = 0;
61/*@}*/
62#endif
63
64/**
65 * Allocated pointers.
66 *
67 * This structure keeps track of the pointer array which represents
68 * pointers allocated via the memory management interface.
69 *
70 * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, spifmem_memrec_t_struct
71 * @ingroup DOXGRP_MEM
72 */
73static spifmem_memrec_t malloc_rec;
74/**
75 * Allocated pixmaps.
76 *
77 * This structure keeps track of the pixmap array which represents
78 * pixmaps allocated via the memory management interface.
79 * 43 *
80 * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, spifmem_memrec_t_struct 44 * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, spifmem_memrec_t_struct
81 * @ingroup DOXGRP_MEM 45 * @ingroup DOXGRP_MEM
82 */ 46 */
83static spifmem_memrec_t pixmap_rec; 47static spifmem_memrec_t resource_rec;
84/**
85 * Allocated GC's.
86 *
87 * This structure keeps track of the GC array which represents
88 * X11 Graphics Context objects, or GC's, allocated via the memory
89 * management interface.
90 *
91 * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, spifmem_memrec_t_struct
92 * @ingroup DOXGRP_MEM
93 */
94static spifmem_memrec_t gc_rec;
95 48
96/** 49/**
97 * Initialize memory management system. 50 * Initialize memory management system.
@@ -107,55 +60,46 @@ void
107spifmem_init(void) 60spifmem_init(void)
108{ 61{
109 D_MEM(("Constructing memory allocation records\n")); 62 D_MEM(("Constructing memory allocation records\n"));
110 malloc_rec.ptrs = (spifmem_ptr_t *) malloc(sizeof(spifmem_ptr_t)); 63 resource_rec.ptrs = (spifmem_ptr_t *) malloc(sizeof(spifmem_ptr_t));
111 pixmap_rec.ptrs = (spifmem_ptr_t *) malloc(sizeof(spifmem_ptr_t));
112 gc_rec.ptrs = (spifmem_ptr_t *) malloc(sizeof(spifmem_ptr_t));
113} 64}
114 65
115/** 66/**
116 * Add a variable to a record set. 67 * Add a resource to be tracked.
117 * 68 *
118 * This is the static, internal-use-only function that does the actual
119 * work of recording information on a variable to be tracked. This
120 * information includes file and line number information and is stored
121 * as a #spifmem_ptr_t.
122 *
123 * @param memrec Address of the #spifmem_memrec_t we're adding to.
124 * @param filename The filename where the variable was allocated. 69 * @param filename The filename where the variable was allocated.
125 * @param line The line number of @a filename where the variable 70 * @param line The line number of @a filename where the variable
126 * was allocated. 71 * was allocated.
127 * @param ptr The allocated variable. 72 * @param ptr The allocated variable.
128 * @param size The number of bytes requested. 73 * @param size The size of the resource in bytes.
74 * @param type The type of resource being tracked.
129 * 75 *
130 * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, MALLOC(), libast_malloc() 76 * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, MALLOC(), libast_malloc()
131 * @ingroup DOXGRP_MEM 77 * @ingroup DOXGRP_MEM
132 */ 78 */
133void 79void
134memrec_add_var(spifmem_memrec_t *memrec, const char *filename, unsigned long line, void *ptr, size_t size) 80spifmem_add_var(const char *filename, unsigned long line, void *ptr, size_t size, char *type)
135{ 81{
136 register spifmem_ptr_t *p; 82 register spifmem_ptr_t *p;
137 83
138 ASSERT(memrec != NULL); 84 resource_rec.cnt++;
139 memrec->cnt++; 85 if (!(resource_rec.ptrs = (spifmem_ptr_t *)realloc(resource_rec.ptrs, sizeof(spifmem_ptr_t) * resource_rec.cnt))) {
140 if (!(memrec->ptrs = (spifmem_ptr_t *)realloc(memrec->ptrs, sizeof(spifmem_ptr_t) * memrec->cnt))) {
141 D_MEM(("Unable to reallocate pointer list -- %s\n", strerror(errno))); 86 D_MEM(("Unable to reallocate pointer list -- %s\n", strerror(errno)));
142 } 87 }
143 p = memrec->ptrs + memrec->cnt - 1; 88 p = resource_rec.ptrs + resource_rec.cnt - 1;
144 D_MEM(("Adding variable (%10p, %lu bytes) from %s:%lu.\n", ptr, size, filename, line)); 89 D_MEM(("Adding variable (%10p, %lu bytes) from %s:%lu.\n", ptr, size, filename, line));
145 D_MEM(("Storing as pointer #%lu at %10p (from %10p).\n", memrec->cnt, p, memrec->ptrs)); 90 D_MEM(("Storing as pointer #%lu at %10p (from %10p).\n", resource_rec.cnt, p, resource_rec.ptrs));
146 p->ptr = ptr; 91 p->ptr = ptr;
147 p->size = size; 92 p->size = size;
148 spiftool_safe_strncpy(p->file, (const spif_charptr_t) filename, sizeof(p->file)); 93 spiftool_safe_strncpy(p->file, (const spif_charptr_t) filename, sizeof(p->file));
149 p->line = line; 94 p->line = line;
95 p->type = type;
150} 96}
151 97
152/** 98/**
153 * Find a variable within a record set. 99 * Find a variable within the list of tracked resources.
154 * 100 *
155 * This function searches through the pointer list of the specified 101 * This function searches through the resource list for a given resource ID.
156 * @a memrec object for a given pointer.
157 * 102 *
158 * @param memrec Address of the #spifmem_memrec_t we're searching.
159 * @param ptr The value of the requested pointer. 103 * @param ptr The value of the requested pointer.
160 * @return A pointer to the #spifmem_ptr_t object within @a memrec 104 * @return A pointer to the #spifmem_ptr_t object within @a memrec
161 * that matches @a ptr, or NULL if not found. 105 * 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
164 * @ingroup DOXGRP_MEM 108 * @ingroup DOXGRP_MEM
165 */ 109 */
166spifmem_ptr_t * 110spifmem_ptr_t *
167memrec_find_var(spifmem_memrec_t *memrec, const void *ptr) 111spifmem_find_var(const void *ptr)
168{ 112{
169 register spifmem_ptr_t *p; 113 register spifmem_ptr_t *p;
170 register unsigned long i; 114 register unsigned long i;
171 115
172 ASSERT_RVAL(memrec != NULL, NULL);
173 REQUIRE_RVAL(ptr != NULL, NULL); 116 REQUIRE_RVAL(ptr != NULL, NULL);
174 117
175 for (i = 0, p = memrec->ptrs; i < memrec->cnt; i++, p++) { 118 for (i = 0, p = resource_rec.ptrs; i < resource_rec.cnt; i++, p++) {
176 if (p->ptr == ptr) { 119 if (p->ptr == ptr) {
177 D_MEM(("Found pointer #%lu stored at %10p (from %10p)\n", i + 1, p, memrec->ptrs)); 120 D_MEM(("Found pointer #%lu stored at %10p (from %10p)\n", i + 1, p, resource_rec.ptrs));
178 return p; 121 return p;
179 } 122 }
180 } 123 }
@@ -182,12 +125,8 @@ memrec_find_var(spifmem_memrec_t *memrec, const void *ptr)
182} 125}
183 126
184/** 127/**
185 * Remove a variable from a record set. 128 * Remove a variable from the list of tracked resources.
186 *
187 * This is the static, internal-use-only function that does the actual
188 * work of freeing recorded information for a deleted pointer.
189 * 129 *
190 * @param memrec Address of the #spifmem_memrec_t we're removing from.
191 * @param var The variable name being freed (for diagnostic 130 * @param var The variable name being freed (for diagnostic
192 * purposes only). 131 * purposes only).
193 * @param filename The filename where the variable was freed. 132 * @param filename The filename where the variable was freed.
@@ -199,34 +138,29 @@ memrec_find_var(spifmem_memrec_t *memrec, const void *ptr)
199 * @ingroup DOXGRP_MEM 138 * @ingroup DOXGRP_MEM
200 */ 139 */
201void 140void
202memrec_rem_var(spifmem_memrec_t *memrec, const char *var, const char *filename, unsigned long line, const void *ptr) 141spifmem_rem_var(const char *var, const char *filename, unsigned long line, const void *ptr)
203{ 142{
204 register spifmem_ptr_t *p; 143 register spifmem_ptr_t *p;
205 144
206 ASSERT(memrec != NULL);
207 USE_VAR(var); 145 USE_VAR(var);
208 USE_VAR(filename); 146 USE_VAR(filename);
209 USE_VAR(line); 147 USE_VAR(line);
210 148
211 if (!(p = memrec_find_var(memrec, ptr))) { 149 if (!(p = spifmem_find_var(ptr))) {
212 D_MEM(("ERROR: File %s, line %d attempted to free variable %s (%10p) which was not allocated with MALLOC/REALLOC\n", 150 D_MEM(("ERROR: File %s, line %d attempted to free resource %s (%10p) which was not registered.\n",
213 filename, line, var, ptr)); 151 filename, line, var, ptr));
214 return; 152 return;
215 } 153 }
216 D_MEM(("Removing variable %s (%10p) of size %lu\n", var, ptr, p->size)); 154 D_MEM(("Removing variable %s (%10p) of size %lu\n", var, ptr, p->size));
217 if ((--memrec->cnt) > 0) { 155 if ((--resource_rec.cnt) > 0) {
218 memmove(p, p + 1, sizeof(spifmem_ptr_t) * (memrec->cnt - (p - memrec->ptrs))); 156 memmove(p, p + 1, sizeof(spifmem_ptr_t) * (resource_rec.cnt - (p - resource_rec.ptrs)));
219 memrec->ptrs = (spifmem_ptr_t *) realloc(memrec->ptrs, sizeof(spifmem_ptr_t) * memrec->cnt); 157 resource_rec.ptrs = (spifmem_ptr_t *) realloc(resource_rec.ptrs, sizeof(spifmem_ptr_t) * resource_rec.cnt);
220 } 158 }
221} 159}
222 160
223/** 161/**
224 * Resize a variable in a record set. 162 * Resize a tracked resource.
225 * 163 *
226 * This is the static, internal-use-only function that does the actual
227 * work of altering information on a tracked variable.
228 *
229 * @param memrec Address of the #spifmem_memrec_t we're modifying.
230 * @param var The variable name being resized (for diagnostic 164 * @param var The variable name being resized (for diagnostic
231 * purposes only). 165 * purposes only).
232 * @param filename The filename where the variable was resized. 166 * @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,
240 * @ingroup DOXGRP_MEM 174 * @ingroup DOXGRP_MEM
241 */ 175 */
242void 176void
243memrec_chg_var(spifmem_memrec_t *memrec, const char *var, const char *filename, unsigned long line, const void *oldp, void *newp, size_t size) 177spifmem_chg_var(const char *var, const char *filename, unsigned long line, const void *oldp, void *newp, size_t size)
244{ 178{
245 register spifmem_ptr_t *p; 179 register spifmem_ptr_t *p;
246 180
247 ASSERT(memrec != NULL);
248 USE_VAR(var); 181 USE_VAR(var);
249 182
250 if (!(p = memrec_find_var(memrec, oldp))) { 183 if (!(p = spifmem_find_var(oldp))) {
251 D_MEM(("ERROR: File %s, line %d attempted to realloc variable %s (%10p) which was not allocated with MALLOC/REALLOC\n", filename, 184 D_MEM(("ERROR: File %s, line %d attempted to realloc untracked resource %s (%10p).\n", filename,
252 line, var, oldp)); 185 line, var, oldp));
253 return; 186 return;
254 } 187 }
255 D_MEM(("Changing variable %s (%10p, %lu -> %10p, %lu)\n", var, oldp, p->size, newp, size)); 188 D_MEM(("Changing variable %s (%10p, %lu -> %10p, %lu)\n", var, oldp, p->size, newp, size));
256 p->ptr = newp; 189 p->ptr = newp;
257 p->size = size; 190 p->size = size;
258 spiftool_safe_strncpy(p->file, (const spif_charptr_t) filename, sizeof(p->file)); 191 spiftool_safe_strncpy(p->file, filename, sizeof(p->file));
259 p->line = line; 192 p->line = line;
260} 193}
261 194
262/** 195/**
263 * Dump listing of tracked pointers.
264 *
265 * This function dumps a listing of all pointers in @a memrec along
266 * with the filename, line number, address, size, and contents for
267 * each. Contents are displayed in both hex and ASCII, the latter
268 * having non-printable characters replaced with periods ('.').
269 *
270 * @param memrec Address of the #spifmem_memrec_t we're dumping.
271 *
272 * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, MALLOC_DUMP(), libast_dump_mem_tables()
273 * @ingroup DOXGRP_MEM
274 */
275void
276memrec_dump_pointers(spifmem_memrec_t *memrec)
277{
278 register spifmem_ptr_t *p;
279 unsigned long i, j, k, l, total = 0;
280 unsigned long len;
281 spif_char_t buff[9];
282
283 ASSERT(memrec != NULL);
284 fprintf(LIBAST_DEBUG_FD, "PTR: %lu pointers stored.\n", (unsigned long) memrec->cnt);
285 fprintf(LIBAST_DEBUG_FD,
286 "PTR: Pointer | Filename | Line | Address | Size | Offset | 00 01 02 03 04 05 06 07 | ASCII \n");
287 fprintf(LIBAST_DEBUG_FD,
288 "PTR: ---------+----------------------+--------+----------+--------+---------+-------------------------+---------\n");
289 fflush(LIBAST_DEBUG_FD);
290 len = sizeof(spifmem_ptr_t) * memrec->cnt;
291 memset(buff, 0, sizeof(buff));
292
293 /* First, dump the contents of the memrec->ptrs[] array. */
294 for (p = memrec->ptrs, j = 0; j < len; j += 8) {
295 fprintf(LIBAST_DEBUG_FD, "PTR: %07lu | %20s | %6lu | %10p | %06lu | %07x | ",
296 (unsigned long) 0, "", (unsigned long) 0,
297 (spif_ptr_t) memrec->ptrs,
298 (unsigned long) (sizeof(spifmem_ptr_t) * memrec->cnt), (unsigned int) j);
299 /* l is the number of characters we're going to output */
300 l = ((len - j < 8) ? (len - j) : (8));
301 /* Copy l bytes (up to 8) from memrec->ptrs[] (p) to buffer */
302 memcpy(buff, ((char *) p) + j, l);
303 buff[l] = 0;
304 for (k = 0; k < l; k++) {
305 fprintf(LIBAST_DEBUG_FD, "%02x ", buff[k]);
306 }
307 /* If we printed less than 8 bytes worth, pad with 3 spaces per byte */
308 for (; k < 8; k++) {
309 fprintf(LIBAST_DEBUG_FD, " ");
310 }
311 /* Finally, print the printable ASCII string for those l bytes */
312 fprintf(LIBAST_DEBUG_FD, "| %-8s\n", spiftool_safe_str((char *) buff, l));
313 /* Flush after every line in case we crash */
314 fflush(LIBAST_DEBUG_FD);
315 }
316
317 /* Now print out each pointer and its contents. */
318 for (i = 0; i < memrec->cnt; p++, i++) {
319 /* Add this pointer's size to our total */
320 total += p->size;
321 for (j = 0; j < p->size; j += 8) {
322 fprintf(LIBAST_DEBUG_FD, "PTR: %07lu | %20s | %6lu | %10p | %06lu | %07x | ",
323 i + 1, NONULL(p->file), (unsigned long) p->line,
324 p->ptr, (unsigned long) p->size, (unsigned) j);
325 /* l is the number of characters we're going to output */
326 l = ((p->size - j < 8) ? (p->size - j) : (8));
327 /* Copy l bytes (up to 8) from p->ptr to buffer */
328 memcpy(buff, ((char *) p->ptr) + j, l);
329 buff[l] = 0;
330 for (k = 0; k < l; k++) {
331 fprintf(LIBAST_DEBUG_FD, "%02x ", buff[k]);
332 }
333 /* If we printed less than 8 bytes worth, pad with 3 spaces per byte */
334 for (; k < 8; k++) {
335 fprintf(LIBAST_DEBUG_FD, " ");
336 }
337 /* Finally, print the printable ASCII string for those l bytes */
338 fprintf(LIBAST_DEBUG_FD, "| %-8s\n", spiftool_safe_str(buff, l));
339 /* Flush after every line in case we crash */
340 fflush(LIBAST_DEBUG_FD);
341 }
342 }
343 fprintf(LIBAST_DEBUG_FD, "PTR: Total allocated memory: %10lu bytes\n", total);
344 fflush(LIBAST_DEBUG_FD);
345}
346
347/**
348 * Dump listing of tracked resources. 196 * Dump listing of tracked resources.
349 * 197 *
350 * This function is very similar to memrec_dump_pointers() but is
351 * intended for use with non-pointer data.
352 *
353 * @param memrec Address of the #spifmem_memrec_t we're dumping.
354 *
355 * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, MALLOC_DUMP(), libast_dump_mem_tables(), 198 * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, MALLOC_DUMP(), libast_dump_mem_tables(),
356 * memrec_dump_pointers() 199 * spifmem_dump_pointers()
357 * @ingroup DOXGRP_MEM 200 * @ingroup DOXGRP_MEM
358 */ 201 */
359void 202void
360memrec_dump_resources(spifmem_memrec_t *memrec) 203spifmem_dump_resources(void)
361{ 204{
362 register spifmem_ptr_t *p; 205 register spifmem_ptr_t *p;
363 unsigned long i, total; 206 unsigned long i, total;
364 unsigned long len; 207 unsigned long len;
365 208
366 ASSERT(memrec != NULL); 209 len = resource_rec.cnt;
367 len = memrec->cnt;
368 fprintf(LIBAST_DEBUG_FD, "RES: %lu resources stored.\n", 210 fprintf(LIBAST_DEBUG_FD, "RES: %lu resources stored.\n",
369 (unsigned long) memrec->cnt); 211 (unsigned long) resource_rec.cnt);
370 fprintf(LIBAST_DEBUG_FD, "RES: Index | Resource ID | Filename | Line | Size \n"); 212 fprintf(LIBAST_DEBUG_FD, "RES: Index | Resource ID | Filename | Line | Size | Type\n");
371 fprintf(LIBAST_DEBUG_FD, "RES: -------+-------------+----------------------+--------+--------\n"); 213 fprintf(LIBAST_DEBUG_FD, "RES: -------+-------------+----------------------+--------+--------+----------\n");
372 fflush(LIBAST_DEBUG_FD); 214 fflush(LIBAST_DEBUG_FD);
373 215
374 for (p = memrec->ptrs, i = 0, total = 0; i < len; i++, p++) { 216 for (p = resource_rec.ptrs, i = 0, total = 0; i < len; i++, p++) {
375 total += p->size; 217 total += p->size;
376 fprintf(LIBAST_DEBUG_FD, "RES: %5lu | 0x%08lx | %20s | %6lu | %6lu\n", 218 fprintf(LIBAST_DEBUG_FD, "RES: %5lu | 0x%08lx | %20s | %6lu | %6lu | %-8s\n",
377 i, (unsigned long) p->ptr, NONULL(p->file), 219 i, (unsigned long) p->ptr, NONULL(p->file), (unsigned long) p->line,
378 (unsigned long) p->line, 220 (unsigned long) p->size, p->type);
379 (unsigned long) p->size);
380 /* Flush after every line in case we crash */ 221 /* Flush after every line in case we crash */
381 fflush(LIBAST_DEBUG_FD); 222 fflush(LIBAST_DEBUG_FD);
382 } 223 }
@@ -384,468 +225,6 @@ memrec_dump_resources(spifmem_memrec_t *memrec)
384 fflush(LIBAST_DEBUG_FD); 225 fflush(LIBAST_DEBUG_FD);
385} 226}
386 227
387/******************** MEMORY ALLOCATION INTERFACE ********************/
388
389/**
390 * LibAST implementation of malloc().
391 *
392 * When memory debugging is active (via #DEBUG_MEM), all calls to the
393 * MALLOC() macro are routed here. The macro allows filename and line
394 * number information to be provided thanks to the __FILE__ and
395 * __LINE__ symbols pre-defined by cpp.
396 *
397 * @param filename The filename where the variable is being
398 * allocated.
399 * @param line The line number of @a filename where the variable
400 * is being allocated.
401 * @param size The requested size in bytes (as passed to MALLOC()).
402 * @return A pointer to the newly-allocated memory.
403 *
404 * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, MALLOC()
405 * @ingroup DOXGRP_MEM
406 */
407void *
408spifmem_malloc(const char *filename, unsigned long line, size_t size)
409{
410 void *temp;
411
412#if MALLOC_CALL_COUNT
413 ++malloc_count;
414 if (!(malloc_count % MALLOC_CALL_INTERVAL)) {
415 fprintf(LIBAST_DEBUG_FD, "Calls to malloc(): %d\n", malloc_count);
416 }
417#endif
418
419 D_MEM(("%lu bytes requested at %s:%lu\n", size, NONULL(filename), line));
420
421 temp = (void *) malloc(size);
422 ASSERT_RVAL(!SPIF_PTR_ISNULL(temp), (spif_ptr_t) NULL);
423 if (DEBUG_LEVEL >= DEBUG_MEM) {
424 memrec_add_var(&malloc_rec, NONULL(filename), line, temp, size);
425 }
426 return (temp);
427}
428
429/**
430 * LibAST implementation of realloc().
431 *
432 * When memory debugging is active (via #DEBUG_MEM), all calls to the
433 * REALLOC() macro are routed here. The macro allows variable name,
434 * filename, and line number information to be provided.
435 *
436 * @param var The variable name being resized.
437 * @param filename The filename where the variable is being
438 * reallocated.
439 * @param line The line number of @a filename where the variable
440 * is being reallocated.
441 * @param ptr The old value of the pointer being resized.
442 * @param size The new requested size in bytes (as passed to
443 * REALLOC()).
444 * @return The new value (possibly moved) of the pointer.
445 *
446 * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, REALLOC()
447 * @ingroup DOXGRP_MEM
448 */
449void *
450spifmem_realloc(const char *var, const char *filename, unsigned long line, void *ptr, size_t size)
451{
452 void *temp;
453
454#if MALLOC_CALL_COUNT
455 ++realloc_count;
456 if (!(realloc_count % REALLOC_CALL_INTERVAL)) {
457 D_MEM(("Calls to realloc(): %d\n", realloc_count));
458 }
459#endif
460
461 D_MEM(("Variable %s (%10p -> %lu) at %s:%lu\n", var, ptr, (unsigned long) size, NONULL(filename), line));
462 if (!ptr) {
463 temp = (void *) spifmem_malloc(filename, line, size);
464 } else if (size == 0) {
465 spifmem_free(var, filename, line, ptr);
466 temp = NULL;
467 } else {
468 temp = (void *) realloc(ptr, size);
469 ASSERT_RVAL(!SPIF_PTR_ISNULL(temp), (spif_ptr_t) NULL);
470 if (DEBUG_LEVEL >= DEBUG_MEM) {
471 memrec_chg_var(&malloc_rec, var, NONULL(filename), line, ptr, temp, size);
472 }
473 }
474 return (temp);
475}
476
477/**
478 * LibAST implementation of calloc().
479 *
480 * When memory debugging is active (via #DEBUG_MEM), all calls to the
481 * CALLOC() macro are routed here. The macro allows filename and line
482 * number information to be provided thanks to the __FILE__ and
483 * __LINE__ symbols pre-defined by cpp.
484 *
485 * @param filename The filename where the variable is being
486 * allocated.
487 * @param line The line number of @a filename where the variable
488 * is being allocated.
489 * @param count The number of objects being allocated.
490 * @param size The size in bytes of each object (as passed to
491 * CALLOC()).
492 * @return A pointer to the newly-allocated, zeroed memory.
493 *
494 * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, CALLOC()
495 * @ingroup DOXGRP_MEM
496 */
497void *
498spifmem_calloc(const char *filename, unsigned long line, size_t count, size_t size)
499{
500 void *temp;
501 size_t total_size;
502
503 total_size = size * count;
504#if MALLOC_CALL_COUNT
505 ++calloc_count;
506 if (!(calloc_count % CALLOC_CALL_INTERVAL)) {
507 fprintf(LIBAST_DEBUG_FD, "Calls to calloc(): %d\n", calloc_count);
508 }
509#endif
510
511 D_MEM(("%lu units of %lu bytes each (%lu bytes total) requested at %s:%lu\n",
512 count, size, total_size, NONULL(filename), line));
513 temp = (void *) calloc(count, size);
514 ASSERT_RVAL(!SPIF_PTR_ISNULL(temp), (spif_ptr_t) NULL);
515 if (DEBUG_LEVEL >= DEBUG_MEM) {
516 memrec_add_var(&malloc_rec, NONULL(filename), line, temp, total_size);
517 }
518 return (temp);
519}
520
521/**
522 * LibAST implementation of free().
523 *
524 * When memory debugging is active (via #DEBUG_MEM), all calls to the
525 * FREE() macro are routed here. The macro allows variable name,
526 * filename, and line number information to be provided.
527 *
528 * @param var The variable name being freed.
529 * @param filename The filename where the variable is being freed.
530 * @param line The line number of @a filename where the variable
531 * is being freed.
532 * @param ptr The pointer being freed (as passed to FREE()).
533 *
534 * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, FREE()
535 * @ingroup DOXGRP_MEM
536 */
537void
538spifmem_free(const char *var, const char *filename, unsigned long line, void *ptr)
539{
540#if MALLOC_CALL_COUNT
541 ++free_count;
542 if (!(free_count % FREE_CALL_INTERVAL)) {
543 fprintf(LIBAST_DEBUG_FD, "Calls to free(): %d\n", free_count);
544 }
545#endif
546
547 D_MEM(("Variable %s (%10p) at %s:%lu\n", var, ptr, NONULL(filename), line));
548 if (ptr) {
549 if (DEBUG_LEVEL >= DEBUG_MEM) {
550 memrec_rem_var(&malloc_rec, var, NONULL(filename), line, ptr);
551 }
552 free(ptr);
553 } else {
554 D_MEM(("ERROR: Caught attempt to free NULL pointer\n"));
555 }
556}
557
558/**
559 * LibAST implementation of strdup().
560 *
561 * When memory debugging is active (via #DEBUG_MEM), all calls to the
562 * STRDUP() macro are routed here. The macro allows variable name,
563 * filename, and line number information to be provided.
564 *
565 * @param var The variable name being duplicated.
566 * @param filename The filename where the variable is being duplicated.
567 * @param line The line number of @a filename where the variable
568 * is being duplicated.
569 * @param str The string being duplicated (as passed to STRDUP()).
570 * @return A pointer to a newly-allocated copy of @a str.
571 *
572 * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, STRDUP()
573 * @ingroup DOXGRP_MEM
574 */
575char *
576spifmem_strdup(const char *var, const char *filename, unsigned long line, const char *str)
577{
578 register char *newstr;
579 register size_t len;
580
581 ASSERT_RVAL(!SPIF_PTR_ISNULL(str), (char *) NULL);
582 USE_VAR(var);
583 D_MEM(("Variable %s (%10p) at %s:%lu\n", var, str, NONULL(filename), line));
584
585 len = strlen((char *) str) + 1; /* Copy NUL byte also */
586 newstr = (char *) spifmem_malloc(NONULL(filename), line, len);
587 ASSERT_RVAL(!SPIF_PTR_ISNULL(newstr), (spif_ptr_t) NULL);
588 strcpy((char *) newstr, (char *) str);
589 return (newstr);
590}
591
592/**
593 * Dump listing of tracked pointers.
594 *
595 * This function simply calls memrec_dump_pointers() and passes in the
596 * address of the #malloc_rec variable.
597 *
598 * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, MALLOC_DUMP(), memrec_dump_pointers()
599 * @ingroup DOXGRP_MEM
600 */
601void
602spifmem_dump_mem_tables(void)
603{
604 fprintf(LIBAST_DEBUG_FD, "Dumping memory allocation table:\n");
605 memrec_dump_pointers(&malloc_rec);
606}
607
608#if LIBAST_X11_SUPPORT
609
610/******************** PIXMAP ALLOCATION INTERFACE ********************/
611
612/**
613 * LibAST implementation of XCreatePixmap().
614 *
615 * When memory debugging is active (via #DEBUG_MEM), all calls to the
616 * X_CREATE_PIXMAP() macro are routed here. The macro allows filename
617 * and line number information to be provided thanks to the __FILE__
618 * and __LINE__ symbols pre-defined by cpp.
619 *
620 * @param filename The filename where the pixmap is being created.
621 * @param line The line number of @a filename where the pixmap is
622 * being created.
623 * @param d The Display for the new pixmap.
624 * @param win The Drawable for the new pixmap.
625 * @param w Width of the pixmap, in pixels.
626 * @param h Height of the pixmap, in pixels.
627 * @param depth The color depth for the new pixmap.
628 * @return A newly-created Pixmap.
629 *
630 * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, X_CREATE_PIXMAP()
631 * @ingroup DOXGRP_MEM
632 */
633Pixmap
634spifmem_x_create_pixmap(const char *filename, unsigned long line, Display * d, Drawable win, unsigned int w, unsigned int h,
635 unsigned int depth)
636{
637 Pixmap p;
638
639 p = XCreatePixmap(d, win, w, h, depth);
640 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));
641 ASSERT_RVAL(p != None, None);
642 if (DEBUG_LEVEL >= DEBUG_MEM) {
643 memrec_add_var(&pixmap_rec, NONULL(filename), line, (void *) p, w * h * (depth / 8));
644 }
645 return (p);
646}
647
648/**
649 * LibAST implementation of XFreePixmap().
650 *
651 * When memory debugging is active (via #DEBUG_MEM), all calls to the
652 * X_FREE_PIXMAP() macro are routed here. The macro allows variable
653 * name, filename, and line number information to be provided.
654 *
655 * @param var The variable name of the pixmap being freed.
656 * @param filename The filename where the pixmap is being freed.
657 * @param line The line number of @a filename where the pixmap is
658 * being freed.
659 * @param d The Display for the pixmap.
660 * @param p The Pixmap to be freed.
661 *
662 * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, X_FREE_PIXMAP()
663 * @ingroup DOXGRP_MEM
664 */
665void
666spifmem_x_free_pixmap(const char *var, const char *filename, unsigned long line, Display * d, Pixmap p)
667{
668 D_MEM(("Freeing pixmap %s (0x%08x) at %s:%lu\n", var, p, NONULL(filename), line));
669 if (p) {
670 if (DEBUG_LEVEL >= DEBUG_MEM) {
671 memrec_rem_var(&pixmap_rec, var, NONULL(filename), line, (void *) p);
672 }
673 XFreePixmap(d, p);
674 } else {
675 D_MEM(("ERROR: Caught attempt to free NULL pixmap\n"));
676 }
677}
678
679# if LIBAST_IMLIB2_SUPPORT
680/**
681 * Register a pixmap for tracking.
682 *
683 * Imlib has its own mechanism for creating pixmaps internally. In
684 * order to keep track of these pixmaps, they must be registered with
685 * LibAST using this function (via the IMLIB_REGISTER_PIXMAP() macro).
686 *
687 * @param var The variable name of the pixmap being registered.
688 * @param filename The filename where the pixmap is being registered.
689 * @param line The line number of @a filename where the pixmap is
690 * being registered.
691 * @param p The Pixmap being registered.
692 *
693 * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, IMLIB_REGISTER_PIXMAP()
694 * @ingroup DOXGRP_MEM
695 */
696void
697spifmem_imlib_register_pixmap(const char *var, const char *filename, unsigned long line, Pixmap p)
698{
699 USE_VAR(var);
700 D_MEM(("Registering pixmap %s (0x%08x) created by Imlib2 at %s:%lu\n", var, p, NONULL(filename), line));
701 if (p) {
702 if (DEBUG_LEVEL >= DEBUG_MEM) {
703 if (!memrec_find_var(&pixmap_rec, (void *) p)) {
704 memrec_add_var(&pixmap_rec, NONULL(filename), line, (void *) p, 1);
705 } else {
706 D_MEM(("Pixmap 0x%08x already registered.\n"));
707 }
708 }
709 } else {
710 D_MEM(("ERROR: Refusing to register a NULL pixmap\n"));
711 }
712}
713
714/**
715 * Free a pixmap created by Imlib.
716 *
717 * Imlib has its own mechanism for freeing pixmaps, and their
718 * associated mask (if any), internally. All pixmaps created by Imlib
719 * must also be freed by Imlib. It is safe, albeit a bit slower, to
720 * free all pixmaps via Imlib, regardless of how they were created.
721 *
722 * @param var The variable name of the pixmap being freed.
723 * @param filename The filename where the pixmap is being freed.
724 * @param line The line number of @a filename where the pixmap is
725 * being freed.
726 * @param p The Pixmap being freed.
727 *
728 * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, IMLIB_FREE_PIXMAP()
729 * @ingroup DOXGRP_MEM
730 */
731void
732spifmem_imlib_free_pixmap(const char *var, const char *filename, unsigned long line, Pixmap p)
733{
734 D_MEM(("Freeing pixmap %s (0x%08x) at %s:%lu using Imlib2\n", var, p, NONULL(filename), line));
735 if (p) {
736 if (DEBUG_LEVEL >= DEBUG_MEM) {
737 memrec_rem_var(&pixmap_rec, var, NONULL(filename), line, (void *) p);
738 }
739 imlib_free_pixmap_and_mask(p);
740 } else {
741 D_MEM(("ERROR: Caught attempt to free NULL pixmap\n"));
742 }
743}
744# endif
745
746/**
747 * Dump listing of tracked pixmaps.
748 *
749 * This function simply calls memrec_dump_resources() and passes in
750 * the address of the #pixmap_rec variable.
751 *
752 * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, PIXMAP_DUMP(), memrec_dump_resources()
753 * @ingroup DOXGRP_MEM
754 */
755void
756spifmem_dump_pixmap_tables(void)
757{
758 fprintf(LIBAST_DEBUG_FD, "Dumping X11 Pixmap allocation table:\n");
759 memrec_dump_resources(&pixmap_rec);
760}
761
762
763
764/********************** GC ALLOCATION INTERFACE **********************/
765
766/**
767 * LibAST implementation of XCreateGC().
768 *
769 * When memory debugging is active (via #DEBUG_MEM), all calls to the
770 * X_CREATE_GC() macro are routed here. The macro allows filename
771 * and line number information to be provided thanks to the __FILE__
772 * and __LINE__ symbols pre-defined by cpp.
773 *
774 * @param filename The filename where the GC is being created.
775 * @param line The line number of @a filename where the GC is
776 * being created.
777 * @param d The Display for the new GC.
778 * @param win The Drawable for the new GC.
779 * @param mask Bitwise OR of zero or more GC flags.
780 * @param gcv Pointer to XGCValues structure.
781 * @return A newly-created GC.
782 *
783 * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, X_CREATE_GC()
784 * @ingroup DOXGRP_MEM
785 */
786GC
787spifmem_x_create_gc(const char *filename, unsigned long line, Display * d, Drawable win, unsigned long mask, XGCValues * gcv)
788{
789 GC gc;
790
791 D_MEM(("Creating gc for window 0x%08x at %s:%lu\n", win, NONULL(filename), line));
792
793 gc = XCreateGC(d, win, mask, gcv);
794 ASSERT_RVAL(gc != None, None);
795 if (DEBUG_LEVEL >= DEBUG_MEM) {
796 memrec_add_var(&gc_rec, NONULL(filename), line, (void *) gc, sizeof(XGCValues));
797 }
798 return (gc);
799}
800
801/**
802 * LibAST implementation of XFreeGC().
803 *
804 * When memory debugging is active (via #DEBUG_MEM), all calls to the
805 * X_FREE_GC() macro are routed here. The macro allows variable
806 * name, filename, and line number information to be provided.
807 *
808 * @param var The variable name of the GC being freed.
809 * @param filename The filename where the GC is being freed.
810 * @param line The line number of @a filename where the GC is
811 * being freed.
812 * @param d The Display for the GC.
813 * @param gc The GC to be freed.
814 *
815 * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, X_FREE_GC()
816 * @ingroup DOXGRP_MEM
817 */
818void
819spifmem_x_free_gc(const char *var, const char *filename, unsigned long line, Display * d, GC gc)
820{
821 D_MEM(("spifmem_x_free_gc() called for variable %s (0x%08x) at %s:%lu\n", var, gc, NONULL(filename), line));
822 if (gc) {
823 if (DEBUG_LEVEL >= DEBUG_MEM) {
824 memrec_rem_var(&gc_rec, var, NONULL(filename), line, (void *) gc);
825 }
826 XFreeGC(d, gc);
827 } else {
828 D_MEM(("ERROR: Caught attempt to free NULL GC\n"));
829 }
830}
831
832/**
833 * Dump listing of tracked GC's.
834 *
835 * This function simply calls memrec_dump_resources() and passes in
836 * the address of the #gc_rec variable.
837 *
838 * @see @link DOXGRP_MEM Memory Management Subsystem @endlink, GC_DUMP(), memrec_dump_resources()
839 * @ingroup DOXGRP_MEM
840 */
841void
842spifmem_dump_gc_tables(void)
843{
844 fprintf(LIBAST_DEBUG_FD, "Dumping X11 GC allocation table:\n");
845 memrec_dump_resources(&gc_rec);
846}
847#endif
848
849/** 228/**
850 * Free an array of pointers. 229 * Free an array of pointers.
851 * 230 *
@@ -886,27 +265,34 @@ spiftool_free_array(void *list, size_t count)
886 * This group of functions/defines/macros implements the memory 265 * This group of functions/defines/macros implements the memory
887 * management subsystem within LibAST. 266 * management subsystem within LibAST.
888 * 267 *
889 * LibAST provides a robust mechanism for tracking memory allocations 268 * LibAST provides a mechanism for tracking resource allocations and
890 * and deallocations. This system employs macro-based wrappers 269 * deallocations. This system employs macro-based wrappers around
891 * around the standard libc malloc/realloc/calloc/free routines, other 270 * various resource allocators/deallocators such as Xlib GC and Pixmap
892 * libc fare such as strdup(), Xlib GC and Pixmap create/free 271 * create/free routines and Imlib2 pixmap functions.
893 * routines, and even Imlib2's own pixmap functions.
894 * 272 *
895 * To take advantage of this system, simply substitute the macro 273 * To take advantage of this system, simply substitute the macro
896 * versions in place of the standard versions throughout your code 274 * versions in place of the standard versions throughout your code
897 * (e.g., use MALLOC() instead of malloc(), X_FREE_GC() instead of 275 * (e.g., X_FREE_GC() instead of XFreeGC()). If DEBUG is set to a
898 * XFreeGC(), etc.). If DEBUG is set to a value higher than 276 * value higher than DEBUG_MEM, the LibAST-custom versions of these
899 * DEBUG_MEM, the LibAST-custom versions of these functions will be 277 * functions will be used. Of course, if memory debugging has not
900 * used. Of course, if memory debugging has not been requested, the 278 * been requested, the original libc/XLib/Imlib2 versions will be used
901 * original libc/XLib/Imlib2 versions will be used instead, so that 279 * instead, so that you only incur the debugging overhead when you
902 * you only incur the debugging overhead when you want it. 280 * want it.
903 * 281 *
904 * LibAST has also been designed to work effectively with Gray 282 * You can also define your own macros to wrap allocators and
905 * Watson's excellent malloc-debugging library, dmalloc 283 * deallocators if LibAST doesn't already contain support for the
906 * (http://dmalloc.com/), either instead of or in addition to its own 284 * resources you wish to track. Simply call spifmem_add_var(),
907 * memory tracking routines. Unlike LibAST, dmalloc supplements 285 * spifmem_chg_var(), and spifmem_rem_var() whenever the resource is
908 * memory allocation tracking with fence-post checking, freed pointer 286 * created, resized, or deleted (respectively).
909 * reuse detection, and other very handy features. 287 *
288 * NOTE: If your compiler does not support compound statement
289 * expressions (i.e., a code block whose final statement specifies the
290 * value of a parenthesized expression, such as:
291 * ({int a = 1, b = 2; a *= b; b += a; a+b;})),
292 * LibAST's built-in wrapper macros will not be available to you, nor
293 * are you likely to be able to wrap many allocator functions with
294 * your own macros. In these situations, you'll need to call the
295 * LibAST memory routines separately.
910 * 296 *
911 * A small sample program demonstrating use of LibAST's memory 297 * A small sample program demonstrating use of LibAST's memory
912 * management system can be found 298 * management system can be found
@@ -927,20 +313,20 @@ spiftool_free_array(void *list, size_t count)
927 * @code 313 * @code
928 * $ ./mem_example 314 * $ ./mem_example
929 * [1045859036] mem.c | 246: spifmem_malloc(): 500 bytes requested at mem_example.c:27 315 * [1045859036] mem.c | 246: spifmem_malloc(): 500 bytes requested at mem_example.c:27
930 * [1045859036] mem.c | 74: memrec_add_var(): Adding variable (0x8049a20, 500 bytes) from mem_example.c:27. 316 * [1045859036] mem.c | 74: spifmem_add_var(): Adding variable (0x8049a20, 500 bytes) from mem_example.c:27.
931 * [1045859036] mem.c | 75: memrec_add_var(): Storing as pointer #1 at 0x8049c18 (from 0x8049c18). 317 * [1045859036] mem.c | 75: spifmem_add_var(): Storing as pointer #1 at 0x8049c18 (from 0x8049c18).
932 * [1045859036] mem.c | 329: spifmem_strdup(): Variable pointer (0x8049a20) at mem_example.c:36 318 * [1045859036] mem.c | 329: spifmem_strdup(): Variable pointer (0x8049a20) at mem_example.c:36
933 * [1045859036] mem.c | 246: spifmem_malloc(): 16 bytes requested at mem_example.c:36 319 * [1045859036] mem.c | 246: spifmem_malloc(): 16 bytes requested at mem_example.c:36
934 * [1045859036] mem.c | 74: memrec_add_var(): Adding variable (0x8049c40, 16 bytes) from mem_example.c:36. 320 * [1045859036] mem.c | 74: spifmem_add_var(): Adding variable (0x8049c40, 16 bytes) from mem_example.c:36.
935 * [1045859036] mem.c | 75: memrec_add_var(): Storing as pointer #2 at 0x8049c7c (from 0x8049c58). 321 * [1045859036] mem.c | 75: spifmem_add_var(): Storing as pointer #2 at 0x8049c7c (from 0x8049c58).
936 * [1045859036] mem.c | 312: spifmem_free(): Variable dup (0x8049c40) at mem_example.c:39 322 * [1045859036] mem.c | 312: spifmem_free(): Variable dup (0x8049c40) at mem_example.c:39
937 * [1045859036] mem.c | 94: memrec_find_var(): Found pointer #2 stored at 0x8049c7c (from 0x8049c58) 323 * [1045859036] mem.c | 94: spifmem_find_var(): Found pointer #2 stored at 0x8049c7c (from 0x8049c58)
938 * [1045859036] mem.c | 113: memrec_rem_var(): Removing variable dup (0x8049c40) of size 16 324 * [1045859036] mem.c | 113: spifmem_rem_var(): Removing variable dup (0x8049c40) of size 16
939 * [1045859036] mem.c | 312: spifmem_free(): Variable dup ( (nil)) at mem_example.c:43 325 * [1045859036] mem.c | 312: spifmem_free(): Variable dup ( (nil)) at mem_example.c:43
940 * [1045859036] mem.c | 319: spifmem_free(): ERROR: Caught attempt to free NULL pointer 326 * [1045859036] mem.c | 319: spifmem_free(): ERROR: Caught attempt to free NULL pointer
941 * [1045859036] mem.c | 268: spifmem_realloc(): Variable pointer (0x8049a20 -> 1000) at mem_example.c:46 327 * [1045859036] mem.c | 268: spifmem_realloc(): Variable pointer (0x8049a20 -> 1000) at mem_example.c:46
942 * [1045859036] mem.c | 94: memrec_find_var(): Found pointer #1 stored at 0x8049c58 (from 0x8049c58) 328 * [1045859036] mem.c | 94: spifmem_find_var(): Found pointer #1 stored at 0x8049c58 (from 0x8049c58)
943 * [1045859036] mem.c | 132: memrec_chg_var(): Changing variable pointer (0x8049a20, 500 -> 0x8049c80, 1000) 329 * [1045859036] mem.c | 132: spifmem_chg_var(): Changing variable pointer (0x8049a20, 500 -> 0x8049c80, 1000)
944 * Dumping memory allocation table: 330 * Dumping memory allocation table:
945 * PTR: 1 pointers stored. 331 * PTR: 1 pointers stored.
946 * PTR: Pointer | Filename | Line | Address | Size | Offset | 00 01 02 03 04 05 06 07 | ASCII 332 * PTR: Pointer | Filename | Line | Address | Size | Offset | 00 01 02 03 04 05 06 07 | ASCII