34#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
35 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
36struct dmalloc_preamble *dmalloc_list;
37unsigned long dmalloc_outstanding;
38unsigned long dmalloc_longterm;
39unsigned long dmalloc_generation;
40unsigned long dmalloc_cutoff_generation;
43#if defined (DEBUG_RC_HISTORY)
44struct rc_history_entry rc_history [RC_HISTORY_MAX];
49#if defined (DEBUG_RC_HISTORY)
50static void print_rc_hist_entry (
int);
53static int dmalloc_failures;
54static char out_of_memory[] =
"Run out of memory.";
61#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
62 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
64 struct dmalloc_preamble *dp;
75 if (dmalloc_failures > 10) {
79 strlen(out_of_memory)));
82 }
else if (dmalloc_failures >= 10) {
89 memset (bar, 0, size);
91#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
92 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
93 dp = (
struct dmalloc_preamble *)foo;
94 dp -> prev = dmalloc_list;
96 dmalloc_list -> next = dp;
98 dp -> next = (
struct dmalloc_preamble *)0;
102 dp -> generation = dmalloc_generation++;
103 dmalloc_outstanding += size;
104 for (i = 0; i < DMLFSIZE; i++)
105 dp -> low_fence [i] =
107 (&dp -> low_fence [i])) % 143) + 113;
111 (&foo [i + size])) % 143) + 113;
112#if defined (DEBUG_MALLOC_POOL_EXHAUSTIVELY)
114 for (dp = dmalloc_list; dp; dp = dp -> prev) {
115 for (i = 0; i < DMLFSIZE; i++) {
116 if (dp -> low_fence [i] !=
118 (&dp -> low_fence [i])) % 143) + 113)
120 log_error (
"malloc fence modified: %s(%d)",
125 foo = (
unsigned char *)dp;
127 if (foo [i + dp -> size] !=
129 (&foo [i + dp -> size])) % 143) + 113) {
130 log_error (
"malloc fence modified: %s(%d)",
138#ifdef DEBUG_REFCNT_DMALLOC_FREE
150#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
151 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
153 unsigned char *bar = ptr;
154 struct dmalloc_preamble *dp, *cur;
157 cur = (
struct dmalloc_preamble *)bar;
158 for (dp = dmalloc_list; dp; dp = dp -> prev)
162 log_error (
"%s(%d): freeing unknown memory: %lx",
167 dp -> prev -> next = dp -> next;
169 dp -> next -> prev = dp -> prev;
170 if (dp == dmalloc_list)
171 dmalloc_list = dp -> prev;
172 if (dp -> generation >= dmalloc_cutoff_generation)
173 dmalloc_outstanding -= dp -> size;
175 dmalloc_longterm -= dp -> size;
177 for (i = 0; i < DMLFSIZE; i++) {
178 if (dp -> low_fence [i] !=
180 (&dp -> low_fence [i])) % 143) + 113)
182 log_error (
"malloc fence modified: %s(%d)",
188 if (bar [i + dp -> size] !=
190 (&bar [i + dp -> size])) % 143) + 113) {
191 log_error (
"malloc fence modified: %s(%d)",
199#ifdef DEBUG_REFCNT_DMALLOC_FREE
201 0, (
unsigned char *)ptr +
DMDOFFSET, 0, 1, RC_MALLOC);
206#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
207 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
213 struct dmalloc_preamble *dp;
223 if (dp -> generation == dmalloc_generation)
229 if (dp -> generation < dmalloc_cutoff_generation && justref)
234 dp -> prev -> next = dp -> next;
236 dp -> next -> prev = dp -> prev;
237 if (dp == dmalloc_list)
238 dmalloc_list = dp -> prev;
241 if (dp -> generation >= dmalloc_cutoff_generation)
242 dmalloc_outstanding -= dp -> size;
244 dmalloc_longterm -= dp -> size;
247 dp -> prev = dmalloc_list;
249 dmalloc_list -> next = dp;
251 dp -> next = (
struct dmalloc_preamble *)0;
258 dp -> generation = dmalloc_generation++;
261 dmalloc_outstanding += dp -> size;
264void dmalloc_dump_outstanding ()
266 static unsigned long dmalloc_cutoff_point;
267 struct dmalloc_preamble *dp;
268#if defined(DEBUG_MALLOC_POOL)
273 if (!dmalloc_cutoff_point)
274 dmalloc_cutoff_point = dmalloc_cutoff_generation;
275 for (dp = dmalloc_list; dp; dp = dp -> prev) {
276 if (dp -> generation <= dmalloc_cutoff_point)
278#if defined (DEBUG_MALLOC_POOL)
279 for (i = 0; i < DMLFSIZE; i++) {
280 if (dp -> low_fence [i] !=
282 (&dp -> low_fence [i])) % 143) + 113)
284 log_error (
"malloc fence modified: %s(%d)",
289 foo = (
unsigned char *)dp;
291 if (foo [i + dp -> size] !=
293 (&foo [i + dp -> size])) % 143) + 113) {
294 log_error (
"malloc fence modified: %s(%d)",
300#if defined (DEBUG_MEMORY_LEAKAGE) || \
301 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
305#if defined (DEBUG_RC_HISTORY)
306 int i, count, inhistory = 0, noted = 0;
310 if (rc_history_count < RC_HISTORY_MAX) {
311 count = rc_history_count;
313 count = RC_HISTORY_MAX;
314 i = rc_history_index - 1;
319 if (rc_history [i].addr == dp + 1) {
323 dp ->
line, (
long) dp -> size);
326 print_rc_hist_entry (i);
327 if (!rc_history [i].refcnt)
331 i = RC_HISTORY_MAX - 1;
342 dmalloc_cutoff_point = dmalloc_list -> generation;
346#if defined (DEBUG_RC_HISTORY)
347static void print_rc_hist_entry (
int i)
349 log_info (
" referenced by %s(%d)[%lx]: addr = %lx refcnt = %x",
350 rc_history [i].
file, rc_history [i].
line,
351 (
unsigned long)rc_history [i].reference,
352 (
unsigned long)rc_history [i].addr,
353 rc_history [i].refcnt);
356void dump_rc_history (
void *addr)
360 i = rc_history_index;
361 if (!rc_history [i].
file)
363 else if (rc_history_count < RC_HISTORY_MAX) {
364 i -= rc_history_count;
368 rc_history_count = 0;
370 while (rc_history [i].
file) {
371 if (!addr || addr == rc_history [i].addr)
372 print_rc_hist_entry (i);
374 if (i == RC_HISTORY_MAX)
376 if (i == rc_history_index)
380void rc_history_next (
int d)
382#if defined (RC_HISTORY_COMPRESSION)
383 int i, j = 0, m, n = 0;
390 m = rc_history_index - 1000;
393 ap = rc_history [rc_history_index].addr;
394 rp = rc_history [rc_history_index].reference;
395 for (i = rc_history_index - 1; i > m; i--) {
396 if (rc_history [i].addr == ap) {
397 if (rc_history [i].reference == rp) {
399 for (n = i; n <= rc_history_index; n++)
400 print_rc_hist_entry (n);
403 memmove (&rc_history [i],
405 (
unsigned)((rc_history_index - i) *
406 sizeof (
struct rc_history_entry)));
409 for (j = i; j < rc_history_count; j++) {
410 if (rc_history [j].addr == ap)
411 --rc_history [j].refcnt;
414 for (n = i; n <= rc_history_index; n++)
415 print_rc_hist_entry (n);
425 if (++rc_history_index == RC_HISTORY_MAX)
426 rc_history_index = 0;
431#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
432 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
434 struct dmalloc_preamble *dp;
438static int dmalloc_find_entry (
struct dmalloc_preamble *dp,
439 struct caller *array,
444 middle = (min + max) / 2;
447 if (array [middle].dp ->
file == dp ->
file) {
448 if (array [middle].dp ->
line == dp ->
line)
451 return dmalloc_find_entry (dp, array, middle, max);
453 return dmalloc_find_entry (dp, array, 0, middle);
455 return dmalloc_find_entry (dp, array, middle, max);
457 return dmalloc_find_entry (dp, array, 0, middle);
462 struct dmalloc_preamble *dp;
464 struct caller cp [1024];
469 memset (cp, 0,
sizeof cp);
470 for (dp = dmalloc_list; dp; dp = dp -> prev) {
471 i = dmalloc_find_entry (dp, cp, 0, ccur);
476 log_error (
"no space for memory usage summary.");
486 memmove (cp + i + 2, cp + i + 1,
487 (ccur - i) *
sizeof *cp);
489 cp [i + 1].count = 1;
491 }
else if (cp [i].dp ->
file != dp ->
file ||
494 cp + i, (ccur - i) *
sizeof *cp);
501 printf (
"%d\t%s:%d\n", i, dp ->
file, dp ->
line);
502 dump_rc_history (dp + 1);
505 for (i = 0; i < ccur; i++) {
506 printf (
"%d\t%s:%d\t%d\n", i,
507 cp [i].dp ->
file, cp [i].dp ->
line, cp [i].count);
508#if defined(DUMP_RC_HISTORY)
509 dump_rc_history (cp [i].dp + 1);
524 if (type -> allocator) {
526 status = (*type -> allocator) (&foo,
file,
line);
527 tsize = type -> size;
529 status = ISC_R_NOMEMORY;
533 if (status == ISC_R_NOMEMORY) {
535 tsize = (*type -> sizer) (size);
537 tsize = type -> size;
545 return ISC_R_NOMEMORY;
561 size_t usize,
size_t psize,
564 memset (o, 0, psize);
566 if (type -> initialize)
567 (*type -> initialize) (o,
file,
line);
579#if defined (POINTER_DEBUG)
580 log_error (
"%s(%d): reference store into non-null pointer!",
596 int outer_reference = 0;
597 int inner_reference = 0;
598 int handle_reference = 0;
599 int extra_references;
606#if defined (POINTER_DEBUG)
614 if ((*h) -> refcnt <= 0) {
615#if defined (POINTER_DEBUG)
616 log_error (
"%s(%d): dereference of pointer with refcnt of zero!",
618#if defined (DEBUG_RC_HISTORY)
619 dump_rc_history (*h);
631 if ((*h) -> inner && (*h) -> inner -> outer &&
632 h != &((*h) -> inner -> outer))
636 if ((*h) -> outer && (*h) -> outer -> inner &&
637 h != &((*h) -> outer -> inner))
647 handle_reference = 1;
655 if ((*h) -> refcnt ==
656 inner_reference + outer_reference + handle_reference + 1) {
657 if (inner_reference || outer_reference || handle_reference) {
660 extra_references = 0;
661 for (p = (*h) -> inner;
662 p && !extra_references; p = p -> inner) {
663 extra_references += p -> refcnt;
664 if (p -> inner && p -> inner -> outer == p)
671 for (p = (*h) -> outer;
672 p && !extra_references; p = p -> outer) {
673 extra_references += p -> refcnt;
674 if (p -> outer && p -> outer -> inner == p)
682 extra_references = 0;
684 if (!extra_references) {
696 0, 1, hp -> type -> rc_flag);
697 if (handle_reference) {
704 if (hp -> type -> destroy)
705 (*(hp -> type -> destroy)) (hp,
file,
line);
706 if (hp -> type -> freer)
707 (hp -> type -> freer (hp,
file,
line));
714 h, *h, (*h) -> refcnt, 1,
715 (*h) -> type -> rc_flag);
721 (*h) -> type -> rc_flag);
735 return ISC_R_NOMEMORY;
736 memset (t, 0,
sizeof *t);
740 (*h) -> head =
sizeof ((*h) -> buf) - 1;
752#if defined (POINTER_DEBUG)
753 log_error (
"%s(%d): reference store into non-null pointer!",
773#if defined (POINTER_DEBUG)
781 if ((*h) -> refcnt <= 0) {
782#if defined (POINTER_DEBUG)
783 log_error (
"%s(%d): dereference of pointer with refcnt of zero!",
785#if defined (DEBUG_RC_HISTORY)
786 dump_rc_history (*h);
797 if ((*h) -> refcnt == 0)
821 intval = va_arg (l,
int);
824 s = va_arg (l,
char *);
833 val = va_arg (l,
unsigned);
852 return ISC_R_NOMEMORY;
853 memset (
new, 0, len);
857 new -> u.integer = intval;
860 memcpy (
new -> u.buffer.value, s, val);
861 new -> u.buffer.len = val;
864 new -> u.buffer.len = val;
888#if defined (POINTER_DEBUG)
908#if defined (POINTER_DEBUG)
916 if ((*h) -> refcnt <= 0) {
917#if defined (POINTER_DEBUG)
918 log_error (
"%s(%d): dereference of pointer with refcnt of zero!",
920#if defined (DEBUG_RC_HISTORY)
921 dump_rc_history (*h);
932 if ((*h) -> refcnt <= 0 ) {
933 switch ((*h) -> type) {
961 return ISC_R_NOMEMORY;
975#if defined (POINTER_DEBUG)
995#if defined (POINTER_DEBUG)
1003 if ((*h) -> refcnt <= 0) {
1004#if defined (POINTER_DEBUG)
1005 log_error (
"%s(%d): dereference of pointer with refcnt of zero!",
1007#if defined (DEBUG_RC_HISTORY)
1008 dump_rc_history (*h);
1019 if ((*h) -> refcnt <= 0 ) {
1033 return ISC_R_NOMEMORY;
1034 memset (
new, 0,
sizeof *
new);
1046#if defined (POINTER_DEBUG)
1047 log_error (
"%s(%d): reference store into non-null pointer!",
1067#if defined (POINTER_DEBUG)
1075 if ((*h) -> refcnt <= 0) {
1076#if defined (POINTER_DEBUG)
1077 log_error (
"%s(%d): dereference of pointer with refcnt of zero!",
1079#if defined (DEBUG_RC_HISTORY)
1080 dump_rc_history (*h);
1091 if ((*h) -> refcnt == 0) {
1112 return ISC_R_NOMEMORY;
1115 new -> count = count;
1128#if defined (POINTER_DEBUG)
1129 log_error (
"%s(%d): reference store into non-null pointer!",
1149#if defined (POINTER_DEBUG)
1157 if ((*h) -> refcnt <= 0) {
1158#if defined (POINTER_DEBUG)
1159 log_error (
"%s(%d): dereference of pointer with zero refcnt!",
1161#if defined (DEBUG_RC_HISTORY)
1162 dump_rc_history (*h);
1173 if ((*h) -> refcnt <= 0 ) {
#define rc_register(file, line, reference, addr, refcnt, d, f)
struct _omapi_buffer omapi_buffer_t
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_object_reference(omapi_object_t **r, omapi_object_t *h, const char *file, int line)
isc_result_t omapi_value_new(omapi_value_t **d, const char *file, int line)
isc_result_t omapi_value_dereference(omapi_value_t **h, const char *file, int line)
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_addr_list_new(omapi_addr_list_t **d, unsigned count, const char *file, int line)
isc_result_t omapi_typed_data_dereference(omapi_typed_data_t **h, const char *file, int line)
isc_result_t omapi_data_string_new(omapi_data_string_t **d, unsigned len, 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_typed_data_reference(omapi_typed_data_t **r, omapi_typed_data_t *h, const char *file, int line)
isc_result_t omapi_value_reference(omapi_value_t **r, omapi_value_t *h, 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_allocate(omapi_object_t **o, omapi_object_type_t *type, size_t size, const char *file, int line)
isc_result_t omapi_buffer_new(omapi_buffer_t **h, 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)
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)
isc_result_t omapi_buffer_reference(omapi_buffer_t **r, omapi_buffer_t *h, const char *file, int line)
isc_result_t omapi_addr_list_dereference(omapi_addr_list_t **h, const char *file, int line)
void omapi_print_dmalloc_usage_by_caller(void)
struct __omapi_object_type_t omapi_object_type_t
isc_result_t omapi_object_dereference(omapi_object_t **, const char *, int)
#define OMAPI_TYPED_DATA_INT_LEN
#define dmalloc_reuse(x, y, l, z)
struct __omapi_object omapi_object_t
void * dmalloc(size_t, const char *, int)
void dfree(void *, const char *, int)
#define OMAPI_TYPED_DATA_OBJECT_LEN
#define OMAPI_DATA_STRING_EMPTY_SIZE
#define OMAPI_TYPED_DATA_NOBUFFER_LEN
int log_error(const char *,...) __attribute__((__format__(__printf__
int int int log_debug(const char *,...) __attribute__((__format__(__printf__
void log_fatal(const char *,...) __attribute__((__format__(__printf__
isc_result_t omapi_handle_clear(omapi_handle_t)
int int log_info(const char *,...) __attribute__((__format__(__printf__
#define DHCP_R_INVALIDARG