aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--awk.h14
-rwxr-xr-xconfigure2
-rw-r--r--configure.ac2
-rw-r--r--node.c21
5 files changed, 47 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 5769a718..a64478c0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
2019-08-30 Andrew J. Schorr <aschorr@telemetry-investments.com>
+ * configure.ac (.developing): Add -DMEMDEBUG to CFLAGS.
+ * awk.h (block_header): If MEMDEBUG is defined, add cnt field
+ to track the number of allocations.
+ (getblock, freeblock): When MEMDEBUG is defined, replace these
+ macros with calls to new functions r_getblock and r_freeblock.
+ * node.c (r_getblock, r_freeblock): New functions that simply
+ use malloc and free when MEMDEBUG is defined.
+
+2019-08-30 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
* interpret.h (r_interpret): For Op_match_rec, unref if a
dynamic regexp. Fixes another memory issue. See the thread starting
at https://lists.gnu.org/archive/html/bug-gawk/2019-08/msg00023.html.
diff --git a/awk.h b/awk.h
index 363e4403..345d87b3 100644
--- a/awk.h
+++ b/awk.h
@@ -1061,6 +1061,9 @@ struct block_item {
struct block_header {
struct block_item *freep;
size_t size;
+#ifdef MEMDEBUG
+ long cnt;
+#endif
};
enum block_id {
@@ -1323,12 +1326,23 @@ DEREF(NODE *r)
#define get_lhs(n, r) (n)->type == Node_var && ! var_uninitialized(n) ? \
&((n)->var_value) : r_get_lhs((n), (r))
+#ifdef MEMDEBUG
+
+extern void *r_getblock(int id);
+extern void r_freeblock(void *, int id);
+#define getblock(p, id, ty) (void) (p = r_getblock(id))
+#define freeblock(p, id) (void) (r_freeblock(p, id))
+
+#else /* MEMDEBUG */
+
#define getblock(p, id, ty) (void) ((p = (ty) nextfree[id].freep) ? \
(ty) (nextfree[id].freep = ((struct block_item *) p)->freep) \
: (p = (ty) more_blocks(id)))
#define freeblock(p, id) (void) (((struct block_item *) p)->freep = nextfree[id].freep, \
nextfree[id].freep = (struct block_item *) p)
+#endif /* MEMDEBUG */
+
#define getnode(n) getblock(n, BLOCK_NODE, NODE *)
#define freenode(n) freeblock(n, BLOCK_NODE)
diff --git a/configure b/configure
index a9f5e7c8..ee0bbbfc 100755
--- a/configure
+++ b/configure
@@ -5409,7 +5409,7 @@ $as_echo_n "checking for special development options... " >&6; }
if test -f $srcdir/.developing
then
# add other debug flags as appropriate, save GAWKDEBUG for emergencies
- CFLAGS="$CFLAGS -DARRAYDEBUG -DYYDEBUG -DLOCALEDEBUG"
+ CFLAGS="$CFLAGS -DARRAYDEBUG -DYYDEBUG -DLOCALEDEBUG -DMEMDEBUG"
# turn on compiler warnings if we're doing development
# enable debugging using macros also
diff --git a/configure.ac b/configure.ac
index 436ef4af..7c01f48d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -111,7 +111,7 @@ AC_MSG_CHECKING([for special development options])
if test -f $srcdir/.developing
then
# add other debug flags as appropriate, save GAWKDEBUG for emergencies
- CFLAGS="$CFLAGS -DARRAYDEBUG -DYYDEBUG -DLOCALEDEBUG"
+ CFLAGS="$CFLAGS -DARRAYDEBUG -DYYDEBUG -DLOCALEDEBUG -DMEMDEBUG"
# turn on compiler warnings if we're doing development
# enable debugging using macros also
diff --git a/node.c b/node.c
index 9574c3e7..eacd17b3 100644
--- a/node.c
+++ b/node.c
@@ -1034,6 +1034,25 @@ struct block_header nextfree[BLOCK_MAX] = {
#endif
};
+#ifdef MEMDEBUG
+
+void *
+r_getblock(int id)
+{
+ void *res;
+ emalloc(res, void *, nextfree[id].size, "getblock");
+ nextfree[id].cnt++;
+ return res;
+}
+
+void
+r_freeblock(void *p, int id)
+{
+ nextfree[id].cnt--;
+ free(p);
+}
+
+#else
/* more_blocks --- get more blocks of memory and add to the free list;
size of a block must be >= sizeof(struct block_item)
@@ -1064,3 +1083,5 @@ more_blocks(int id)
nextfree[id].freep = freep->freep;
return freep;
}
+
+#endif