aboutsummaryrefslogtreecommitdiff
path: root/src/debug.c
blob: 3f2b85abe9e05ab2fe8bec135ec33e382b49d6c6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

struct debug_header {
	const char *f;
	unsigned int l;
	size_t s;
	struct debug_header *next, *prev;
};

typedef struct debug_header d_header;

d_header *d_head;

void *
f_debug_mem_malloc(size_t s, const char *f, unsigned int l)
{
	d_header *m = malloc(s + sizeof(*m));
	/* fprintf(stdout, "%s:%u: malloc(%zi)\n", f, l, s); */
	if (m == NULL) return m;
	m->f = f;
	m->l = l;
	m->s = s;
	m->next = d_head;
	if (d_head)
		m->next->prev = m;
	m->prev = NULL;
	d_head = m;
	return m+1;
}

void
f_debug_mem_free(void *s, const char *f, unsigned int l)
{
	d_header *m;
	if (s != NULL) {
		m = (d_header *)s - 1;
		m->s = ~m->s;

		if (m->prev == NULL) {
			assert(d_head == m);
			d_head = m->next;
		} else {
			m->prev->next = m->next;
		}

		if (m->next) m->next->prev = m->prev;
		/* fprintf(stdout, "%s:%u: free()\n", f, l); */
		free(m);
	}
}

void *
f_debug_mem_realloc(void *x, size_t s, const char *f, unsigned int l)
{
	d_header *m;
	void *q;
	if (x == NULL) {
		return f_debug_mem_malloc(s, f, l);
	} else if (s == 0) {
		f_debug_mem_free(x, f, l);
		return NULL;
	} else {
		m = (d_header *)x - 1;
		if (s <= m->s) return x;
		q = f_debug_mem_malloc(s, f, l);
		if (q) {
			memcpy(q, x, m->s);
			f_debug_mem_free(x, f, l);
		}
		return q;
	}
}

void
f_debug_mem_show()
{
	d_header *m = d_head;
	while (m) {
		fprintf(stdout, "%s:%u: %zd bytes at %p\n", m->f, m->l, m->s, (void*)(m+1));
		m = m->next;
	}
}

#include "debug.h"