36 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
37 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
38 struct dmalloc_preamble *dmalloc_list;
39 unsigned long dmalloc_outstanding;
40 unsigned long dmalloc_longterm;
41 unsigned long dmalloc_generation;
42 unsigned long dmalloc_cutoff_generation;
45 #if defined (DEBUG_RC_HISTORY)
46 struct rc_history_entry rc_history [RC_HISTORY_MAX];
51 #if defined (DEBUG_RC_HISTORY)
52 static void print_rc_hist_entry (
int);
60 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
61 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
63 struct dmalloc_preamble *dp;
75 memset (bar, 0, size);
77 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
78 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
79 dp = (
struct dmalloc_preamble *)foo;
80 dp -> prev = dmalloc_list;
82 dmalloc_list -> next = dp;
84 dp -> next = (
struct dmalloc_preamble *)0;
88 dp -> generation = dmalloc_generation++;
89 dmalloc_outstanding += size;
90 for (i = 0; i < DMLFSIZE; i++)
93 (&dp -> low_fence [i])) % 143) + 113;
97 (&foo [i + size])) % 143) + 113;
98 #if defined (DEBUG_MALLOC_POOL_EXHAUSTIVELY)
100 for (dp = dmalloc_list; dp; dp = dp -> prev) {
101 for (i = 0; i < DMLFSIZE; i++) {
102 if (dp -> low_fence [i] !=
104 (&dp -> low_fence [i])) % 143) + 113)
106 log_error (
"malloc fence modified: %s(%d)",
107 dp -> file, dp -> line);
111 foo = (
unsigned char *)dp;
113 if (foo [i + dp -> size] !=
115 (&foo [i + dp -> size])) % 143) + 113) {
116 log_error (
"malloc fence modified: %s(%d)",
117 dp -> file, dp -> line);
124 #ifdef DEBUG_REFCNT_DMALLOC_FREE
133 log_error (
"dfree %s(%d): free on null pointer.", file, line);
136 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
137 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
139 unsigned char *bar = ptr;
140 struct dmalloc_preamble *dp, *cur;
143 cur = (
struct dmalloc_preamble *)bar;
144 for (dp = dmalloc_list; dp; dp = dp -> prev)
148 log_error (
"%s(%d): freeing unknown memory: %lx",
149 file, line, (
unsigned long)cur);
153 dp -> prev -> next = dp -> next;
155 dp -> next -> prev = dp -> prev;
156 if (dp == dmalloc_list)
157 dmalloc_list = dp -> prev;
158 if (dp -> generation >= dmalloc_cutoff_generation)
159 dmalloc_outstanding -= dp -> size;
161 dmalloc_longterm -= dp -> size;
163 for (i = 0; i < DMLFSIZE; i++) {
164 if (dp -> low_fence [i] !=
166 (&dp -> low_fence [i])) % 143) + 113)
168 log_error (
"malloc fence modified: %s(%d)",
169 dp -> file, dp -> line);
174 if (bar [i + dp -> size] !=
176 (&bar [i + dp -> size])) % 143) + 113) {
177 log_error (
"malloc fence modified: %s(%d)",
178 dp -> file, dp -> line);
185 #ifdef DEBUG_REFCNT_DMALLOC_FREE
187 0, (
unsigned char *)ptr +
DMDOFFSET, 0, 1, RC_MALLOC);
192 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
193 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
199 struct dmalloc_preamble *dp;
209 if (dp -> generation == dmalloc_generation)
215 if (dp -> generation < dmalloc_cutoff_generation && justref)
220 dp -> prev -> next = dp -> next;
222 dp -> next -> prev = dp -> prev;
223 if (dp == dmalloc_list)
224 dmalloc_list = dp -> prev;
227 if (dp -> generation >= dmalloc_cutoff_generation)
228 dmalloc_outstanding -= dp -> size;
230 dmalloc_longterm -= dp -> size;
233 dp -> prev = dmalloc_list;
235 dmalloc_list -> next = dp;
237 dp -> next = (
struct dmalloc_preamble *)0;
244 dp -> generation = dmalloc_generation++;
247 dmalloc_outstanding += dp -> size;
250 void dmalloc_dump_outstanding ()
252 static unsigned long dmalloc_cutoff_point;
253 struct dmalloc_preamble *dp;
254 #if defined(DEBUG_MALLOC_POOL)
259 if (!dmalloc_cutoff_point)
260 dmalloc_cutoff_point = dmalloc_cutoff_generation;
261 for (dp = dmalloc_list; dp; dp = dp -> prev) {
262 if (dp -> generation <= dmalloc_cutoff_point)
264 #if defined (DEBUG_MALLOC_POOL)
265 for (i = 0; i < DMLFSIZE; i++) {
266 if (dp -> low_fence [i] !=
268 (&dp -> low_fence [i])) % 143) + 113)
270 log_error (
"malloc fence modified: %s(%d)",
271 dp -> file, dp -> line);
275 foo = (
unsigned char *)dp;
277 if (foo [i + dp -> size] !=
279 (&foo [i + dp -> size])) % 143) + 113) {
280 log_error (
"malloc fence modified: %s(%d)",
281 dp -> file, dp -> line);
286 #if defined (DEBUG_MEMORY_LEAKAGE) || \
287 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
291 #if defined (DEBUG_RC_HISTORY)
292 int i, count, inhistory = 0, noted = 0;
296 if (rc_history_count < RC_HISTORY_MAX) {
297 count = rc_history_count;
299 count = RC_HISTORY_MAX;
300 i = rc_history_index - 1;
305 if (rc_history [i].addr == dp + 1) {
308 log_info (
" %s(%d): %ld", dp -> file,
309 dp -> line, (
long) dp -> size);
312 print_rc_hist_entry (i);
313 if (!rc_history [i].refcnt)
317 i = RC_HISTORY_MAX - 1;
322 dp -> file, dp -> line,
328 dmalloc_cutoff_point = dmalloc_list -> generation;
332 #if defined (DEBUG_RC_HISTORY)
333 static void print_rc_hist_entry (
int i)
335 log_info (
" referenced by %s(%d)[%lx]: addr = %lx refcnt = %x",
336 rc_history [i].file, rc_history [i].line,
337 (
unsigned long)rc_history [i].reference,
338 (
unsigned long)rc_history [i].addr,
339 rc_history [i].refcnt);
342 void dump_rc_history (
void *addr)
346 i = rc_history_index;
347 if (!rc_history [i].file)
349 else if (rc_history_count < RC_HISTORY_MAX) {
350 i -= rc_history_count;
354 rc_history_count = 0;
356 while (rc_history [i].file) {
357 if (!addr || addr == rc_history [i].addr)
358 print_rc_hist_entry (i);
360 if (i == RC_HISTORY_MAX)
362 if (i == rc_history_index)
366 void rc_history_next (
int d)
368 #if defined (RC_HISTORY_COMPRESSION)
369 int i, j = 0, m, n = 0;
376 m = rc_history_index - 1000;
379 ap = rc_history [rc_history_index].addr;
380 rp = rc_history [rc_history_index].reference;
381 for (i = rc_history_index - 1; i > m; i--) {
382 if (rc_history [i].addr == ap) {
383 if (rc_history [i].reference == rp) {
385 for (n = i; n <= rc_history_index; n++)
386 print_rc_hist_entry (n);
389 memmove (&rc_history [i],
391 (
unsigned)((rc_history_index - i) *
392 sizeof (
struct rc_history_entry)));
395 for (j = i; j < rc_history_count; j++) {
396 if (rc_history [j].addr == ap)
397 --rc_history [j].refcnt;
400 for (n = i; n <= rc_history_index; n++)
401 print_rc_hist_entry (n);
411 if (++rc_history_index == RC_HISTORY_MAX)
412 rc_history_index = 0;
417 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
418 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
420 struct dmalloc_preamble *dp;
424 static int dmalloc_find_entry (
struct dmalloc_preamble *dp,
425 struct caller *array,
430 middle = (min + max) / 2;
433 if (array [middle].dp -> file == dp -> file) {
434 if (array [middle].dp -> line == dp -> line)
436 else if (array [middle].dp -> line < dp -> line)
437 return dmalloc_find_entry (dp, array, middle, max);
439 return dmalloc_find_entry (dp, array, 0, middle);
440 }
else if (array [middle].dp -> file < dp -> file)
441 return dmalloc_find_entry (dp, array, middle, max);
443 return dmalloc_find_entry (dp, array, 0, middle);
448 struct dmalloc_preamble *dp;
450 struct caller cp [1024];
455 memset (cp, 0,
sizeof cp);
456 for (dp = dmalloc_list; dp; dp = dp -> prev) {
457 i = dmalloc_find_entry (dp, cp, 0, ccur);
459 cp [i].dp -> file != dp -> file ||
460 cp [i].dp -> line != dp -> line) &&
462 log_error (
"no space for memory usage summary.");
468 }
else if (cp [i].dp -> file < dp -> file ||
469 (cp [i].dp -> file == dp -> file &&
470 cp [i].dp -> line < dp -> line)) {
472 memmove (cp + i + 2, cp + i + 1,
473 (ccur - i) *
sizeof *cp);
475 cp [i + 1].count = 1;
477 }
else if (cp [i].dp -> file != dp -> file ||
478 cp [i].dp -> line != dp -> line) {
480 cp + i, (ccur - i) *
sizeof *cp);
487 printf (
"%d\t%s:%d\n", i, dp -> file, dp -> line);
488 dump_rc_history (dp + 1);
491 for (i = 0; i < ccur; i++) {
492 printf (
"%d\t%s:%d\t%d\n", i,
493 cp [i].dp -> file, cp [i].dp -> line, cp [i].count);
494 #if defined(DUMP_RC_HISTORY)
495 dump_rc_history (cp [i].dp + 1);
504 const char *file,
int line)
510 if (type -> allocator) {
512 status = (*type -> allocator) (&foo, file, line);
513 tsize = type -> size;
515 status = ISC_R_NOMEMORY;
519 if (status == ISC_R_NOMEMORY) {
521 tsize = (*type -> sizer) (size);
523 tsize = type -> size;
529 foo =
dmalloc (tsize, file, line);
531 return ISC_R_NOMEMORY;
535 if (status != ISC_R_SUCCESS) {
537 (*type -> freer) (foo, file, line);
539 dfree (foo, file, line);
547 size_t usize,
size_t psize,
548 const char *file,
int line)
550 memset (o, 0, psize);
552 if (type -> initialize)
553 (*type -> initialize) (o, file, line);
554 return ISC_R_SUCCESS;
559 const char *file,
int line)
565 #if defined (POINTER_DEBUG)
566 log_error (
"%s(%d): reference store into non-null pointer!",
575 rc_register (file, line, r, h, h -> refcnt, 0, h -> type -> rc_flag);
576 return ISC_R_SUCCESS;
580 const char *file,
int line)
582 int outer_reference = 0;
583 int inner_reference = 0;
584 int handle_reference = 0;
585 int extra_references;
592 #if defined (POINTER_DEBUG)
593 log_error (
"%s(%d): dereference of null pointer!", file, line);
600 if ((*h) -> refcnt <= 0) {
601 #if defined (POINTER_DEBUG)
602 log_error (
"%s(%d): dereference of pointer with refcnt of zero!",
604 #if defined (DEBUG_RC_HISTORY)
605 dump_rc_history (*h);
617 if ((*h) -> inner && (*h) -> inner -> outer &&
618 h != &((*h) -> inner -> outer))
622 if ((*h) -> outer && (*h) -> outer -> inner &&
623 h != &((*h) -> outer -> inner))
633 handle_reference = 1;
641 if ((*h) -> refcnt ==
642 inner_reference + outer_reference + handle_reference + 1) {
643 if (inner_reference || outer_reference || handle_reference) {
646 extra_references = 0;
647 for (p = (*h) -> inner;
648 p && !extra_references; p = p -> inner) {
649 extra_references += p -> refcnt;
650 if (p -> inner && p -> inner -> outer == p)
657 for (p = (*h) -> outer;
658 p && !extra_references; p = p -> outer) {
659 extra_references += p -> refcnt;
660 if (p -> outer && p -> outer -> inner == p)
668 extra_references = 0;
670 if (!extra_references) {
676 (&hp -> inner, file, line);
679 (&hp -> outer, file, line);
682 0, 1, hp -> type -> rc_flag);
683 if (handle_reference) {
690 if (hp -> type -> destroy)
691 (*(hp -> type -> destroy)) (hp,
file,
line);
692 if (hp -> type -> freer)
693 (hp -> type -> freer (hp, file, line));
695 dfree (hp, file, line);
700 h, *h, (*h) -> refcnt, 1,
701 (*h) -> type -> rc_flag);
707 (*h) -> type -> rc_flag);
710 return ISC_R_SUCCESS;
714 const char *file,
int line)
721 return ISC_R_NOMEMORY;
722 memset (t, 0,
sizeof *t);
724 if (status != ISC_R_SUCCESS)
725 dfree (t, file, line);
726 (*h) -> head =
sizeof ((*h) -> buf) - 1;
732 const char *file,
int line)
738 #if defined (POINTER_DEBUG)
739 log_error (
"%s(%d): reference store into non-null pointer!",
749 return ISC_R_SUCCESS;
753 const char *file,
int line)
759 #if defined (POINTER_DEBUG)
760 log_error (
"%s(%d): dereference of null pointer!", file, line);
767 if ((*h) -> refcnt <= 0) {
768 #if defined (POINTER_DEBUG)
769 log_error (
"%s(%d): dereference of pointer with refcnt of zero!",
771 #if defined (DEBUG_RC_HISTORY)
772 dump_rc_history (*h);
783 if ((*h) -> refcnt == 0)
784 dfree (*h, file, line);
786 return ISC_R_SUCCESS;
807 intval = va_arg (l,
int);
810 s = va_arg (l,
char *);
819 val = va_arg (l,
unsigned);
836 new =
dmalloc (len, file, line);
838 return ISC_R_NOMEMORY;
839 memset (
new, 0, len);
843 new -> u.integer = intval;
846 memcpy (
new -> u.buffer.value, s, val);
847 new -> u.buffer.len = val;
850 new -> u.buffer.len = val;
855 if (status != ISC_R_SUCCESS) {
856 dfree (
new, file, line);
868 const char *file,
int line)
874 #if defined (POINTER_DEBUG)
875 log_error (
"%s(%d): reference store into non-null pointer!", file, line);
884 return ISC_R_SUCCESS;
888 const char *file,
int line)
894 #if defined (POINTER_DEBUG)
895 log_error (
"%s(%d): dereference of null pointer!", file, line);
902 if ((*h) -> refcnt <= 0) {
903 #if defined (POINTER_DEBUG)
904 log_error (
"%s(%d): dereference of pointer with refcnt of zero!",
906 #if defined (DEBUG_RC_HISTORY)
907 dump_rc_history (*h);
918 if ((*h) -> refcnt <= 0 ) {
919 switch ((*h) -> type) {
930 dfree (*h, file, line);
933 return ISC_R_SUCCESS;
937 const char *file,
int line)
945 new =
dmalloc (nlen, file, line);
947 return ISC_R_NOMEMORY;
955 const char *file,
int line)
961 #if defined (POINTER_DEBUG)
962 log_error (
"%s(%d): reference store into non-null pointer!", file, line);
971 return ISC_R_SUCCESS;
975 const char *file,
int line)
981 #if defined (POINTER_DEBUG)
982 log_error (
"%s(%d): dereference of null pointer!", file, line);
989 if ((*h) -> refcnt <= 0) {
990 #if defined (POINTER_DEBUG)
991 log_error (
"%s(%d): dereference of pointer with refcnt of zero!",
993 #if defined (DEBUG_RC_HISTORY)
994 dump_rc_history (*h);
1005 if ((*h) -> refcnt <= 0 ) {
1006 dfree (*h, file, line);
1009 return ISC_R_SUCCESS;
1013 const char *file,
int line)
1017 new =
dmalloc (
sizeof *
new, file, line);
1019 return ISC_R_NOMEMORY;
1020 memset (
new, 0,
sizeof *
new);
1026 const char *file,
int line)
1032 #if defined (POINTER_DEBUG)
1033 log_error (
"%s(%d): reference store into non-null pointer!",
1043 return ISC_R_SUCCESS;
1047 const char *file,
int line)
1053 #if defined (POINTER_DEBUG)
1054 log_error (
"%s(%d): dereference of null pointer!", file, line);
1061 if ((*h) -> refcnt <= 0) {
1062 #if defined (POINTER_DEBUG)
1063 log_error (
"%s(%d): dereference of pointer with refcnt of zero!",
1065 #if defined (DEBUG_RC_HISTORY)
1066 dump_rc_history (*h);
1077 if ((*h) -> refcnt == 0) {
1084 dfree (*h, file, line);
1087 return ISC_R_SUCCESS;
1091 const char *file,
int line)
1098 return ISC_R_NOMEMORY;
1101 new -> count = count;
1108 const char *file,
int line)
1114 #if defined (POINTER_DEBUG)
1115 log_error (
"%s(%d): reference store into non-null pointer!",
1125 return ISC_R_SUCCESS;
1129 const char *file,
int line)
1135 #if defined (POINTER_DEBUG)
1136 log_error (
"%s(%d): dereference of null pointer!", file, line);
1143 if ((*h) -> refcnt <= 0) {
1144 #if defined (POINTER_DEBUG)
1145 log_error (
"%s(%d): dereference of pointer with zero refcnt!",
1147 #if defined (DEBUG_RC_HISTORY)
1148 dump_rc_history (*h);
1159 if ((*h) -> refcnt <= 0 ) {
1160 dfree (*h, file, line);
1163 return ISC_R_SUCCESS;
#define rc_register(file, line, reference, addr, refcnt, d, f)
isc_result_t omapi_value_new(omapi_value_t **d, const char *file, int line)
isc_result_t omapi_object_reference(omapi_object_t **r, omapi_object_t *h, const char *file, int line)
isc_result_t omapi_typed_data_reference(omapi_typed_data_t **r, omapi_typed_data_t *h, const char *file, int line)
isc_result_t omapi_buffer_reference(omapi_buffer_t **r, omapi_buffer_t *h, const char *file, int line)
isc_result_t omapi_value_dereference(omapi_value_t **h, const char *file, int line)
isc_result_t omapi_object_dereference(omapi_object_t **h, const char *file, int line)
isc_result_t omapi_object_allocate(omapi_object_t **o, omapi_object_type_t *type, size_t size, const char *file, int line)
#define DHCP_R_INVALIDARG
int int int log_debug(const char *,...) __attribute__((__format__(__printf__
isc_result_t omapi_typed_data_new(const char *file, int line, omapi_typed_data_t **t, omapi_datatype_t type,...)
isc_result_t omapi_buffer_new(omapi_buffer_t **h, const char *file, int line)
int log_error(const char *,...) __attribute__((__format__(__printf__
isc_result_t omapi_value_reference(omapi_value_t **r, omapi_value_t *h, const char *file, int line)
void omapi_print_dmalloc_usage_by_caller(void)
#define OMAPI_TYPED_DATA_OBJECT_LEN
isc_result_t omapi_data_string_reference(omapi_data_string_t **r, omapi_data_string_t *h, const char *file, int line)
isc_result_t omapi_data_string_dereference(omapi_data_string_t **h, const char *file, int line)
isc_result_t omapi_addr_list_new(omapi_addr_list_t **d, unsigned count, const char *file, int line)
isc_result_t omapi_addr_list_dereference(omapi_addr_list_t **h, const char *file, int line)
void dfree(void *ptr, const char *file, int line)
isc_result_t omapi_buffer_dereference(omapi_buffer_t **h, const char *file, int line)
isc_result_t omapi_object_initialize(omapi_object_t *o, omapi_object_type_t *type, size_t usize, size_t psize, const char *file, int line)
#define OMAPI_TYPED_DATA_INT_LEN
isc_result_t omapi_typed_data_dereference(omapi_typed_data_t **h, const char *file, int line)
int int log_info(const char *,...) __attribute__((__format__(__printf__
#define OMAPI_TYPED_DATA_NOBUFFER_LEN
void * dmalloc(unsigned size, const char *file, int line)
#define dmalloc_reuse(x, y, l, z)
isc_result_t omapi_handle_clear(omapi_handle_t)
#define OMAPI_DATA_STRING_EMPTY_SIZE
isc_result_t omapi_data_string_new(omapi_data_string_t **d, unsigned len, const char *file, int line)
isc_result_t omapi_addr_list_reference(omapi_addr_list_t **r, omapi_addr_list_t *h, const char *file, int line)