comparison dbmalloc.c @ 1378:7209a6e30932 fuzz

linked list dbmalloc now add non-free m_malloc_free_epoch() argument for leak detection
author Matt Johnston <matt@ucc.asn.au>
date Fri, 26 May 2017 00:19:39 +0800
parents 9aa6cd66b51d
children c42e8ff42bd1
comparison
equal deleted inserted replaced
1377:d4cc85e6c569 1378:7209a6e30932
1 #include "dbmalloc.h" 1 #include "dbmalloc.h"
2 #include "dbutil.h" 2 #include "dbutil.h"
3 3
4 #define LIST_SIZE 1000
5
6 struct dbmalloc_header { 4 struct dbmalloc_header {
7 unsigned int index;
8 unsigned int epoch; 5 unsigned int epoch;
6 struct dbmalloc_header *prev;
7 struct dbmalloc_header *next;
9 }; 8 };
10 9
11 static struct dbmalloc_header* dbmalloc_list[LIST_SIZE]; 10 static void put_alloc(struct dbmalloc_header *header);
11 static void remove_alloc(struct dbmalloc_header *header);
12
13 /* end of the linked list */
14 static struct dbmalloc_header* staple;
12 15
13 unsigned int current_epoch = 0; 16 unsigned int current_epoch = 0;
14 17
15 void m_malloc_set_epoch(unsigned int epoch) { 18 void m_malloc_set_epoch(unsigned int epoch) {
16 current_epoch = epoch; 19 current_epoch = epoch;
17 } 20 }
18 21
19 void m_malloc_free_epoch(unsigned int epoch) { 22 void m_malloc_free_epoch(unsigned int epoch, int dofree) {
20 unsigned int i; 23 struct dbmalloc_header* header;
21 unsigned int freed = 0; 24 struct dbmalloc_header* nextheader = NULL;
22 for (i = 0; i < LIST_SIZE; i++) { 25 struct dbmalloc_header* oldstaple = staple;
23 if (dbmalloc_list[i] != NULL) { 26 staple = NULL;
24 assert(dbmalloc_list[i]->index == i); 27 /* free allocations from this epoch, create a new staple-anchored list from
25 if (dbmalloc_list[i]->epoch == epoch) { 28 the remainder */
26 free(dbmalloc_list[i]); 29 for (header = oldstaple; header; header = nextheader)
27 dbmalloc_list[i] = NULL; 30 {
28 freed++; 31 nextheader = header->next;
32 if (header->epoch == epoch) {
33 if (dofree) {
34 free(header);
29 } 35 }
36 } else {
37 header->prev = NULL;
38 header->next = NULL;
39 put_alloc(header);
30 } 40 }
31 } 41 }
32 TRACE(("free_epoch freed %d", freed))
33 } 42 }
34 43
35 static void put_alloc(struct dbmalloc_header *header) { 44 static void put_alloc(struct dbmalloc_header *header) {
36 unsigned int i; 45 assert(header->next == NULL);
37 for (i = 0; i < LIST_SIZE; i++) { 46 assert(header->prev == NULL);
38 if (dbmalloc_list[i] == NULL) { 47 if (staple) {
39 dbmalloc_list[i] = header; 48 staple->prev = header;
40 header->index = i;
41 return;
42 }
43 } 49 }
44 dropbear_exit("ran out of dbmalloc entries"); 50 header->next = staple;
51 staple = header;
45 } 52 }
46 53
47 static void remove_alloc(struct dbmalloc_header *header) { 54 static void remove_alloc(struct dbmalloc_header *header) {
48 assert(header->index < LIST_SIZE); 55 if (header->prev) {
49 assert(dbmalloc_list[header->index] == header); 56 header->prev->next = header->next;
50 assert(header->epoch == current_epoch); 57 }
51 dbmalloc_list[header->index] = NULL; 58 if (header->next) {
59 header->next->prev = header->prev;
60 }
61 if (staple == header) {
62 staple = header->next;
63 }
64 header->prev = NULL;
65 header->next = NULL;
52 } 66 }
53 67
54 static struct dbmalloc_header* get_header(void* ptr) { 68 static struct dbmalloc_header* get_header(void* ptr) {
55 char* bptr = ptr; 69 char* bptr = ptr;
56 return (struct dbmalloc_header*)&bptr[-sizeof(struct dbmalloc_header)]; 70 return (struct dbmalloc_header*)&bptr[-sizeof(struct dbmalloc_header)];