]> git.ipfire.org Git - thirdparty/dhcp.git/blobdiff - omapip/alloc.c
Fix compilation errors introduced in the last set of checkins.
[thirdparty/dhcp.git] / omapip / alloc.c
index d40287bf099ca4288dc263196560ef6a6b3e6078..dfa55b679a97acda9747cb3f07ecf502433fc8c8 100644 (file)
@@ -4,7 +4,7 @@
    protocol... */
 
 /*
- * Copyright (c) 1996-1999 Internet Software Consortium.
+ * Copyright (c) 1996-2000 Internet Software Consortium.
  * Use is subject to license terms which appear in the file named
  * ISC-LICENSE that should have accompanied this file when you
  * received it.   If a file named ISC-LICENSE did not accompany this
 
 #include <omapip/omapip_p.h>
 
+#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL)
+struct dmalloc_preamble *dmalloc_list;
+unsigned long dmalloc_outstanding;
+unsigned long dmalloc_longterm;
+unsigned long dmalloc_generation;
+unsigned long dmalloc_cutoff_generation;
+#endif
+
+#if defined (DEBUG_RC_HISTORY)
+struct rc_history_entry rc_history [RC_HISTORY_MAX];
+int rc_history_index;
+#endif
+
+VOIDPTR dmalloc (size, file, line)
+       unsigned size;
+       const char *file;
+       int line;
+{
+       unsigned char *foo = dmalloc (size + DMDSIZE, file, line);
+       int i;
+       VOIDPTR *bar;
+#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL)
+       struct dmalloc_preamble *dp;
+#endif
+       if (!foo)
+               return (VOIDPTR)0;
+       bar = (VOIDPTR)(foo + DMDOFFSET);
+       memset (bar, 0, size);
+
+#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL)
+       dp = (struct dmalloc_preamble *)foo;
+       dp -> prev = dmalloc_list;
+       if (dmalloc_list)
+               dmalloc_list -> next = dp;
+       dmalloc_list = dp;
+       dp -> next = (struct dmalloc_preamble *)0;
+       dp -> size = size;
+       dp -> file = file;
+       dp -> line = line;
+       dp -> generation = dmalloc_generation++;
+       dmalloc_outstanding += size;
+       for (i = 0; i < DMLFSIZE; i++)
+               dp -> low_fence [i] =
+                       (((unsigned long)
+                         (&dp -> low_fence [i])) % 143) + 113;
+       for (i = DMDOFFSET; i < DMDSIZE; i++)
+               foo [i + size] =
+                       (((unsigned long)
+                         (&foo [i + size])) % 143) + 113;
+#if defined (DEBUG_MALLOC_POOL_EXHAUSTIVELY)
+       /* Check _every_ entry in the pool!   Very expensive. */
+       for (dp = dmalloc_list; dp; dp = dp -> prev) {
+               for (i = 0; i < DMLFSIZE; i++) {
+                       if (dp -> low_fence [i] !=
+                               (((unsigned long)
+                                 (&dp -> low_fence [i])) % 143) + 113)
+                       {
+                               log_error ("malloc fence modified: %s(%d)",
+                                          dp -> file, dp -> line);
+                               abort ();
+                       }
+               }
+               foo = (unsigned char *)dp;
+               for (i = DMDOFFSET; i < DMDSIZE; i++) {
+                       if (foo [i + dp -> size] !=
+                               (((unsigned long)
+                                 (&foo [i + dp -> size])) % 143) + 113) {
+                               log_error ("malloc fence modified: %s(%d)",
+                                          dp -> file, dp -> line);
+                               abort ();
+                       }
+               }
+       }
+#endif
+#endif
+       return bar;
+}
+
+void dfree (ptr, file, line)
+       VOIDPTR ptr;
+       const char *file;
+       int line;
+{
+       if (!ptr) {
+               log_error ("dfree %s(%d): free on null pointer.", file, line);
+               return;
+       }
+#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL)
+       {
+               unsigned char *bar = ptr;
+               struct dmalloc_preamble *dp, *cur;
+               int i;
+               bar -= DMDOFFSET;
+               cur = (struct dmalloc_preamble *)bar;
+               for (dp = dmalloc_list; dp; dp = dp -> prev)
+                       if (dp == cur)
+                               break;
+               if (!dp) {
+                       log_error ("%s(%d): freeing unknown memory: %lx",
+                                  dp -> file, dp -> line, (unsigned long)cur);
+                       abort ();
+               }
+               if (dp -> prev)
+                       dp -> prev -> next = dp -> next;
+               if (dp -> next)
+                       dp -> next -> prev = dp -> prev;
+               if (dp == dmalloc_list)
+                       dmalloc_list = dp -> prev;
+               if (dp -> generation >= dmalloc_cutoff_generation)
+                       dmalloc_outstanding -= dp -> size;
+               else
+                       dmalloc_longterm -= dp -> size;
+
+               for (i = 0; i < DMLFSIZE; i++) {
+                       if (dp -> low_fence [i] !=
+                               (((unsigned long)
+                                 (&dp -> low_fence [i])) % 143) + 113)
+                       {
+                               log_error ("malloc fence modified: %s(%d)",
+                                          dp -> file, dp -> line);
+                               abort ();
+                       }
+               }
+               for (i = DMDOFFSET; i < DMDSIZE; i++) {
+                       if (bar [i + dp -> size] !=
+                               (((unsigned long)
+                                 (&bar [i + dp -> size])) % 143) + 113) {
+                               log_error ("malloc fence modified: %s(%d)",
+                                          dp -> file, dp -> line);
+                               abort ();
+                       }
+               }
+               ptr = bar;
+       }
+#endif
+       free (ptr);
+}
+
+#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL)
+/* For allocation functions that keep their own free lists, we want to
+   account for the reuse of the memory. */
+
+void dmalloc_reuse (foo, file, line, justref)
+       VOIDPTR foo;
+       const char *file;
+       int line;
+       int justref;
+{
+       struct dmalloc_preamble *dp;
+
+       /* Get the pointer to the dmalloc header. */
+       dp = foo;
+       dp--;
+
+       /* If we just allocated this and are now referencing it, this
+          function would almost be a no-op, except that it would
+          increment the generation count needlessly.  So just return
+          in this case. */
+       if (dp -> generation == dmalloc_generation)
+               return;
+
+       /* If this is longterm data, and we just made reference to it,
+          don't put it on the short-term list or change its name -
+          we don't need to know about this. */
+       if (dp -> generation < dmalloc_cutoff_generation && justref)
+               return;
+
+       /* Take it out of the place in the allocated list where it was. */
+       if (dp -> prev)
+               dp -> prev -> next = dp -> next;
+       if (dp -> next)
+               dp -> next -> prev = dp -> prev;
+       if (dp == dmalloc_list)
+               dmalloc_list = dp -> prev;
+
+       /* Account for its removal. */
+       if (dp -> generation >= dmalloc_cutoff_generation)
+               dmalloc_outstanding -= dp -> size;
+       else
+               dmalloc_longterm -= dp -> size;
+
+       /* Now put it at the head of the list. */
+       dp -> prev = dmalloc_list;
+       if (dmalloc_list)
+               dmalloc_list -> next = dp;
+       dmalloc_list = dp;
+       dp -> next = (struct dmalloc_preamble *)0;
+
+       /* Change the reference location information. */
+       dp -> file = file;
+       dp -> line = line;
+
+       /* Increment the generation. */
+       dp -> generation = dmalloc_generation++;
+
+       /* Account for it. */
+       dmalloc_outstanding += dp -> size;
+}
+
+void dmalloc_dump_outstanding ()
+{
+       static unsigned long dmalloc_cutoff_point;
+       struct dmalloc_preamble *dp;
+       unsigned char *foo;
+       int i;
+
+       if (!dmalloc_cutoff_point)
+               dmalloc_cutoff_point = dmalloc_cutoff_generation;
+       for (dp = dmalloc_list; dp; dp = dp -> prev) {
+               if (dp -> generation <= dmalloc_cutoff_point)
+                       break;
+#if defined (DEBUG_MALLOC_POOL)
+               for (i = 0; i < DMLFSIZE; i++) {
+                       if (dp -> low_fence [i] !=
+                               (((unsigned long)
+                                 (&dp -> low_fence [i])) % 143) + 113)
+                       {
+                               log_error ("malloc fence modified: %s(%d)",
+                                          dp -> file, dp -> line);
+                               abort ();
+                       }
+               }
+               foo = (unsigned char *)dp;
+               for (i = DMDOFFSET; i < DMDSIZE; i++) {
+                       if (foo [i + dp -> size] !=
+                               (((unsigned long)
+                                 (&foo [i + dp -> size])) % 143) + 113) {
+                               log_error ("malloc fence modified: %s(%d)",
+                                          dp -> file, dp -> line);
+                               abort ();
+                       }
+               }
+#endif
+#if defined (DEBUG_MEMORY_LEAKAGE)
+               /* Don't count data that's actually on a free list
+                   somewhere. */
+               if (dp -> file)
+                       log_info ("  %s(%d): %d",
+                                 dp -> file, dp -> line, dp -> size);
+#endif
+       }
+       if (dmalloc_list)
+               dmalloc_cutoff_point = dmalloc_list -> generation;
+}
+#endif /* DEBUG_MEMORY_LEAKAGE || DEBUG_MALLOC_POOL */
+
+#if defined (DEBUG_RC_HISTORY)
+void dump_rc_history ()
+{
+       int i;
+
+       i = rc_history_index;
+       do {
+               log_info ("   referenced by %s(%d): addr = %lx  refcnt = %x\n",
+                         rc_history [i].file, rc_history [i].line,
+                         (unsigned long)rc_history [i].addr,
+                         rc_history [i].refcnt);
+               ++i;
+               if (i == RC_HISTORY_MAX)
+                       i = 0;
+       } while (i != rc_history_index && rc_history [i].file);
+}
+#endif
+
 isc_result_t omapi_object_reference (omapi_object_t **r,
                                     omapi_object_t *h,
                                     const char *file, int line)
@@ -46,7 +310,7 @@ isc_result_t omapi_object_reference (omapi_object_t **r,
 }
 
 isc_result_t omapi_object_dereference (omapi_object_t **h,
-                                      const char *name)
+                                      const char *file, int line)
 {
        int outer_reference = 0;
        int inner_reference = 0;
@@ -59,7 +323,7 @@ isc_result_t omapi_object_dereference (omapi_object_t **h,
 
        if (!*h) {
 #if defined (ALLOCATION_DEBUGGING)
-               abort ("%s: dereference of null pointer!", name);
+               abort ("%s(%d): dereference of null pointer!", file, line);
 #else
                return ISC_R_INVALIDARG;
 #endif
@@ -67,7 +331,8 @@ isc_result_t omapi_object_dereference (omapi_object_t **h,
        
        if ((*h) -> refcnt <= 0) {
 #if defined (ALLOCATION_DEBUGGING)
-               abort ("dereference of pointer with refcnt of zero!");
+               abort ("%s(%d): dereference of pointer with refcnt of zero!",
+                      file, line);
 #else
                return ISC_R_INVALIDARG;
 #endif
@@ -184,7 +449,7 @@ isc_result_t omapi_buffer_reference (omapi_buffer_t **r,
 }
 
 isc_result_t omapi_buffer_dereference (omapi_buffer_t **h,
-                                      const char *name)
+                                      const char *file, int line)
 {
        if (!h)
                return ISC_R_INVALIDARG;
@@ -213,7 +478,8 @@ isc_result_t omapi_buffer_dereference (omapi_buffer_t **h,
        return ISC_R_SUCCESS;
 }
 
-isc_result_t omapi_typed_data_new (omapi_typed_data_t **t,
+isc_result_t omapi_typed_data_new (const char *file, int line,
+                                  omapi_typed_data_t **t,
                                   omapi_datatype_t type, ...)
 {
        va_list l;
@@ -223,8 +489,6 @@ isc_result_t omapi_typed_data_new (omapi_typed_data_t **t,
        int intval;
        char *s;
        isc_result_t status;
-       const char *file;
-       int line;
        omapi_object_t *obj;
 
        va_start (l, type);
@@ -251,10 +515,6 @@ isc_result_t omapi_typed_data_new (omapi_typed_data_t **t,
                return ISC_R_INVALIDARG;
        }
 
-       /* XXX not necessary if not doing malloc debugging. */
-       file = va_arg (l, const char *);
-       line = va_arg (l, int);
-
        new = dmalloc (len, file, line);
        if (!new)
                return ISC_R_NOMEMORY;
@@ -307,14 +567,14 @@ isc_result_t omapi_typed_data_reference (omapi_typed_data_t **r,
 }
 
 isc_result_t omapi_typed_data_dereference (omapi_typed_data_t **h,
-                                          const char *file, line)
+                                          const char *file, int line)
 {
        if (!h)
                return ISC_R_INVALIDARG;
 
        if (!*h) {
 #if defined (ALLOCATION_DEBUGGING)
-               abort ("%s: dereference of null pointer!", name);
+               abort ("%s(%d): dereference of null pointer!", file, line);
 #else
                return ISC_R_INVALIDARG;
 #endif
@@ -322,7 +582,8 @@ isc_result_t omapi_typed_data_dereference (omapi_typed_data_t **h,
        
        if ((*h) -> refcnt <= 0) {
 #if defined (ALLOCATION_DEBUGGING)
-               abort ("dereference of pointer with refcnt of zero!");
+               abort ("%s(%d): dereference of pointer with refcnt of zero!",
+                      file, line);
 #else
                return ISC_R_INVALIDARG;
 #endif
@@ -363,7 +624,7 @@ isc_result_t omapi_data_string_new (omapi_data_string_t **d, unsigned len,
 
 isc_result_t omapi_data_string_reference (omapi_data_string_t **r,
                                          omapi_data_string_t *h,
-                                         const char *file, line)
+                                         const char *file, int line)
 {
        if (!h || !r)
                return ISC_R_INVALIDARG;
@@ -383,7 +644,7 @@ isc_result_t omapi_data_string_reference (omapi_data_string_t **r,
 }
 
 isc_result_t omapi_data_string_dereference (omapi_data_string_t **h,
-                                           const char *file, line)
+                                           const char *file, int line)
 {
        if (!h)
                return ISC_R_INVALIDARG;
@@ -406,7 +667,7 @@ isc_result_t omapi_data_string_dereference (omapi_data_string_t **h,
        }
        
        --((*h) -> refcnt);
-       rc_register (file, line, h, h -> refcnt);
+       rc_register (file, line, h, (*h) -> refcnt);
        if ((*h) -> refcnt <= 0 ) {
                dfree (*h, file, line);
        }
@@ -428,7 +689,7 @@ isc_result_t omapi_value_new (omapi_value_t **d,
 
 isc_result_t omapi_value_reference (omapi_value_t **r,
                                    omapi_value_t *h,
-                                   const char *file, line)
+                                   const char *file, int line)
 {
        if (!h || !r)
                return ISC_R_INVALIDARG;
@@ -449,7 +710,7 @@ isc_result_t omapi_value_reference (omapi_value_t **r,
 }
 
 isc_result_t omapi_value_dereference (omapi_value_t **h,
-                                     const char *name)
+                                     const char *file, int line)
 {
        if (!h)
                return ISC_R_INVALIDARG;
@@ -472,12 +733,14 @@ isc_result_t omapi_value_dereference (omapi_value_t **h,
        }
        
        --((*h) -> refcnt);
-       rc_register (file, line, h, h -> refcnt);
+       rc_register (file, line, h, (*h) -> refcnt);
        if ((*h) -> refcnt <= 0 ) {
                if ((*h) -> name)
-                       omapi_data_string_dereference (&(*h) -> name, name);
+                       omapi_data_string_dereference (&(*h) -> name,
+                                                      file, line);
                if ((*h) -> value)
-                       omapi_typed_data_dereference (&(*h) -> value, name);
+                       omapi_typed_data_dereference (&(*h) -> value,
+                                                     file, line);
                dfree (*h, file, line);
        }
        *h = 0;