Mercurial > dropbear
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)]; |