1. Add the new amalloc module, which (if enabled with

--enable-amalloc) replaced malloc and its ilk with
    versions that attempt to maintain a linked list of
    allocated blocks that can be printed to stderr with
    the `adump()` function.

2.  Clean up a couple more places where I leak memory
    during the first level parse.

3.  tweak cstring.h to try to chase down places where
    the C compiler might optimize EXPAND() into producing
    broken code.
This commit is contained in:
david parsons
2008-04-03 11:22:07 -07:00
parent ce5eaaae07
commit 5c6115c601
15 changed files with 171 additions and 13 deletions
+1 -1
View File
@@ -11,7 +11,7 @@ PGMS=markdown
SAMPLE_PGMS=mkd2html
@THEME@SAMPLE_PGMS+= theme
MKDLIB=libmarkdown.a
OBJS=mkdio.o markdown.o dumptree.o generate.o docheader.o version.o
OBJS=mkdio.o markdown.o dumptree.o generate.o docheader.o version.o @AMALLOC@
all: $(PGMS) $(SAMPLE_PGMS)
+98
View File
@@ -0,0 +1,98 @@
/*
* debugging malloc()/realloc()/calloc()/free() that attempts
* to keep track of just what's been allocated today.
*/
#include <stdio.h>
#include <stdlib.h>
#define MAGIC 0x1f2e3d4c
struct alist { int magic, size; struct alist *next, *last; };
static struct alist list = { 0, 0, 0, 0 };
void *
acalloc(int size, int count)
{
struct alist *ret = calloc(size + sizeof(struct alist), count);
if ( ret ) {
ret->magic = MAGIC;
ret->size = size * count;
if ( list.next ) {
ret->next = list.next;
ret->last = &list;
ret->next->last = ret;
list.next = ret;
}
else {
ret->last = ret->next = &list;
list.next = list.last = ret;
}
return ret+1;
}
return 0;
}
void*
amalloc(int size)
{
return acalloc(size,1);
}
void *
afree(void *ptr)
{
struct alist *p2 = ((struct alist*)ptr)-1;
if ( p2->magic == MAGIC ) {
p2->last->next = p2->next;
p2->next->last = p2->last;
free(p2);
}
else
free(ptr);
}
void *
arealloc(void *ptr, int size)
{
struct alist *p2 = ((struct alist*)ptr)-1;
struct alist save;
if ( p2->magic == MAGIC ) {
save.next = p2->next;
save.last = p2->last;
p2 = realloc(p2, sizeof(p2) + size);
if ( p2 ) {
p2->size = size;
p2->next->last = p2;
p2->last->next = p2;
return p2+1;
}
else {
save.next->last = save.last;
save.last->next = save.next;
return 0;
}
}
return realloc(ptr, size);
}
void
adump()
{
struct alist *p;
for ( p = list.next; p && (p != &list); p = p->next ) {
fprintf(stderr, "allocated: %d byte%s\n", p->size, (p->size==1) ? "" : "s");
fprintf(stderr, " [%.*s]\n", p->size, p+1);
}
}
+29
View File
@@ -0,0 +1,29 @@
/*
* debugging malloc()/realloc()/calloc()/free() that attempts
* to keep track of just what's been allocated today.
*/
#ifndef AMALLOC_D
#define AMALLOC_D
#include "config.h"
#ifdef USE_AMALLOC
extern void *amalloc(int);
extern void *acalloc(int,int);
extern void *arealloc(void*,int);
extern void afree(void*);
extern void adump();
#define malloc amalloc
#define calloc acalloc
#define realloc arealloc
#define free afree
#else
#define adump() (void)1
#endif
#endif/*AMALLOC_D*/
+10 -1
View File
@@ -9,7 +9,8 @@
#
ac_help='--enable-dl-tag Use the DL tag extension
--enable-pandoc-header Use pandoc-style header blocks
--with-tabstops=N Set tabstops to N characters (default is 4)'
--with-tabstops=N Set tabstops to N characters (default is 4)
--enable-amalloc Enable memory allocation debugging'
LOCAL_AC_OPTIONS='
set=`locals $*`;
@@ -99,6 +100,14 @@ fi
AC_DEFINE 'TABSTOP' $TABSTOP
AC_SUB 'TABSTOP' $TABSTOP
if [ "$WITH_AMALLOC" ]; then
AC_DEFINE 'USE_AMALLOC' 1
AC_SUB 'AMALLOC' 'amalloc.o'
else
AC_SUB 'AMALLOC' ''
fi
[ "$OS_FREEBSD" -o "$OS_DRAGONFLY" ] || AC_CHECK_HEADERS malloc.h
[ "$WITH_DL_TAG" ] && AC_DEFINE 'DL_TAG_EXTENSION' '1'
+5 -4
View File
@@ -10,16 +10,17 @@
#include <string.h>
#include <stdlib.h>
#include "amalloc.h"
/* expandable Pascal-style string.
*/
#define STRING(type) struct { type *text; int size, alloc; }
#define RESERVE(x,c) (x).text = malloc(sizeof T(x)[0] * (((x).size=0),((x).alloc=(c))) )
#define CREATE(x) RESERVE(x,100)
#define EXPAND(x) (x).text[((x).size < (x).alloc \
? 0 \
: !((x).text = realloc((x).text, sizeof T(x)[0] * ((x).alloc += 100)))), \
(x).size++]
#define EXPAND(x) ((x).size++)[((x).size < (x).alloc) \
? (x).text \
: (x).text = realloc((x).text, sizeof T(x)[0] * ((x).alloc += 100))]
#define DELETE(x) (x).alloc ? (free(T(x)), S(x) = (x).alloc = 0) \
: ( S(x) = 0 )
+1
View File
@@ -12,6 +12,7 @@
#include "cstring.h"
#include "markdown.h"
#include "amalloc.h"
#define afterdle(t) (T((t)->text) + (t)->dle)
+1
View File
@@ -7,6 +7,7 @@
#include <stdio.h>
#include "markdown.h"
#include "cstring.h"
#include "amalloc.h"
struct frame {
int indent;
+1 -1
View File
@@ -15,6 +15,7 @@
#include "cstring.h"
#include "markdown.h"
#include "amalloc.h"
/* prefixes for <automatic links>
*/
@@ -1196,4 +1197,3 @@ mkd_style(Document *d, FILE *f)
return stylesheets(d->code, f);
return EOF;
}
+2
View File
@@ -15,6 +15,7 @@
#include <string.h>
#include "config.h"
#include "amalloc.h"
#if HAVE_LIBGEN_H
#include <libgen.h>
@@ -137,5 +138,6 @@ main(int argc, char **argv)
rc = mkd_dump(doc, stdout, 0, argc ? basename(argv[0]) : "stdin");
else
rc = markdown(doc, stdout, flags);
adump();
exit( (rc == 0) ? 0 : errno );
}
+18 -6
View File
@@ -15,6 +15,7 @@
#include "cstring.h"
#include "markdown.h"
#include "amalloc.h"
/* block-level tags for passing html blocks through the blender
*/
@@ -669,7 +670,12 @@ listblock(Paragraph *top, int trim, MMIOT *f)
if ( !(q = skipempty(text)) || (islist(q,&trim) != top->typ) )
break;
para = (q != text);
if ( para = (q != text) ) {
Line anchor;
anchor.next = text;
freeLineRange(&anchor, q);
}
if ( para && (top->typ != DL) ) p->down->align = PARA;
}
@@ -699,7 +705,7 @@ addfootnote(Line *p, MMIOT* f)
{
int j, i;
int c;
Line *p2 = p->next;
Line *np = p->next;
Footnote *foot = &EXPAND(f->footnotes);
@@ -729,9 +735,11 @@ addfootnote(Line *p, MMIOT* f)
}
if ( (j >= S(p->text)) && p2 && p2->dle && tgood(T(p2->text)[p2->dle]) ) {
j = p2->dle;
p = p2;
if ( (j >= S(p->text)) && np && np->dle && tgood(T(np->text)[np->dle]) ) {
freeLine(p);
p = np;
np = p->next;
j = p->dle;
}
if ( (c = tgood(T(p->text)[j])) ) {
@@ -751,7 +759,8 @@ addfootnote(Line *p, MMIOT* f)
EXPAND(foot->title) = 0;
}
return p->next;
freeLine(p);
return np;
}
@@ -798,6 +807,7 @@ compile(Line *ptr, int toplevel, MMIOT *f)
ParagraphRoot d = { 0, 0 };
Paragraph *p = 0;
char *key;
Line *r;
int para = toplevel;
int hdr_type, list_type, indent;
@@ -817,7 +827,9 @@ compile(Line *ptr, int toplevel, MMIOT *f)
}
else if ( ishr(ptr) ) {
p = Pp(&d, 0, HR);
r = ptr;
ptr = ptr->next;
freeLine(r);
}
else if (( list_type = islist(ptr, &indent) )) {
p = Pp(&d, ptr, list_type);
+1
View File
@@ -2,6 +2,7 @@
#define _MARKDOWN_D
#include "cstring.h"
#include "amalloc.h"
/* reference-style links (and images) are stored in an array
* of footnotes.
+1
View File
@@ -35,6 +35,7 @@
#include "mkdio.h"
#include "cstring.h"
#include "amalloc.h"
char *pgm = "mkd2html";
+1
View File
@@ -12,6 +12,7 @@
#include "cstring.h"
#include "markdown.h"
#include "amalloc.h"
typedef ANCHOR(Line) LineAnchor;
+1
View File
@@ -2,6 +2,7 @@
#define _MKDIO_D
#include <stdio.h>
#include "amalloc.h"
typedef void MMIOT;
+1
View File
@@ -31,6 +31,7 @@
#include "mkdio.h"
#include "cstring.h"
#include "amalloc.h"
char *pgm = "theme";
char *output = 0;