Home | History | Annotate | Download | only in dbus
      1 /* -*- mode: C; c-file-style: "gnu" -*- */
      2 /* dbus-memory.c  D-Bus memory handling
      3  *
      4  * Copyright (C) 2002, 2003  Red Hat Inc.
      5  *
      6  * Licensed under the Academic Free License version 2.1
      7  *
      8  * This program is free software; you can redistribute it and/or modify
      9  * it under the terms of the GNU General Public License as published by
     10  * the Free Software Foundation; either version 2 of the License, or
     11  * (at your option) any later version.
     12  *
     13  * This program is distributed in the hope that it will be useful,
     14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16  * GNU General Public License for more details.
     17  *
     18  * You should have received a copy of the GNU General Public License
     19  * along with this program; if not, write to the Free Software
     20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     21  *
     22  */
     23 
     24 #include "dbus-memory.h"
     25 #include "dbus-internals.h"
     26 #include "dbus-sysdeps.h"
     27 #include "dbus-list.h"
     28 #include <stdlib.h>
     29 
     30 /**
     31  * @defgroup DBusMemory Memory Allocation
     32  * @ingroup  DBus
     33  * @brief dbus_malloc(), dbus_free(), etc.
     34  *
     35  * Functions and macros related to allocating and releasing
     36  * blocks of memory.
     37  *
     38  */
     39 
     40 /**
     41  * @defgroup DBusMemoryInternals Memory allocation implementation details
     42  * @ingroup  DBusInternals
     43  * @brief internals of dbus_malloc() etc.
     44  *
     45  * Implementation details related to allocating and releasing blocks
     46  * of memory.
     47  */
     48 
     49 /**
     50  * @addtogroup DBusMemory
     51  *
     52  * @{
     53  */
     54 
     55 /**
     56  * @def dbus_new
     57  *
     58  * Safe macro for using dbus_malloc(). Accepts the type
     59  * to allocate and the number of type instances to
     60  * allocate as arguments, and returns a memory block
     61  * cast to the desired type, instead of as a void*.
     62  *
     63  * @param type type name to allocate
     64  * @param count number of instances in the allocated array
     65  * @returns the new memory block or #NULL on failure
     66  */
     67 
     68 /**
     69  * @def dbus_new0
     70  *
     71  * Safe macro for using dbus_malloc0(). Accepts the type
     72  * to allocate and the number of type instances to
     73  * allocate as arguments, and returns a memory block
     74  * cast to the desired type, instead of as a void*.
     75  * The allocated array is initialized to all-bits-zero.
     76  *
     77  * @param type type name to allocate
     78  * @param count number of instances in the allocated array
     79  * @returns the new memory block or #NULL on failure
     80  */
     81 
     82 /**
     83  * @typedef DBusFreeFunction
     84  *
     85  * The type of a function which frees a block of memory.
     86  *
     87  * @param memory the memory to free
     88  */
     89 
     90 /** @} */ /* end of public API docs */
     91 
     92 /**
     93  * @addtogroup DBusMemoryInternals
     94  *
     95  * @{
     96  */
     97 
     98 #ifdef DBUS_BUILD_TESTS
     99 static dbus_bool_t debug_initialized = FALSE;
    100 static int fail_nth = -1;
    101 static size_t fail_size = 0;
    102 static int fail_alloc_counter = _DBUS_INT_MAX;
    103 static int n_failures_per_failure = 1;
    104 static int n_failures_this_failure = 0;
    105 static dbus_bool_t guards = FALSE;
    106 static dbus_bool_t disable_mem_pools = FALSE;
    107 static dbus_bool_t backtrace_on_fail_alloc = FALSE;
    108 static DBusAtomic n_blocks_outstanding = {0};
    109 
    110 /** value stored in guard padding for debugging buffer overrun */
    111 #define GUARD_VALUE 0xdeadbeef
    112 /** size of the information about the block stored in guard mode */
    113 #define GUARD_INFO_SIZE 8
    114 /** size of the GUARD_VALUE-filled padding after the header info  */
    115 #define GUARD_START_PAD 16
    116 /** size of the GUARD_VALUE-filled padding at the end of the block */
    117 #define GUARD_END_PAD 16
    118 /** size of stuff at start of block */
    119 #define GUARD_START_OFFSET (GUARD_START_PAD + GUARD_INFO_SIZE)
    120 /** total extra size over the requested allocation for guard stuff */
    121 #define GUARD_EXTRA_SIZE (GUARD_START_OFFSET + GUARD_END_PAD)
    122 
    123 static void
    124 _dbus_initialize_malloc_debug (void)
    125 {
    126   if (!debug_initialized)
    127     {
    128       debug_initialized = TRUE;
    129 
    130       if (_dbus_getenv ("DBUS_MALLOC_FAIL_NTH") != NULL)
    131 	{
    132 	  fail_nth = atoi (_dbus_getenv ("DBUS_MALLOC_FAIL_NTH"));
    133           fail_alloc_counter = fail_nth;
    134           _dbus_verbose ("Will fail malloc every %d times\n", fail_nth);
    135 	}
    136 
    137       if (_dbus_getenv ("DBUS_MALLOC_FAIL_GREATER_THAN") != NULL)
    138         {
    139           fail_size = atoi (_dbus_getenv ("DBUS_MALLOC_FAIL_GREATER_THAN"));
    140           _dbus_verbose ("Will fail mallocs over %ld bytes\n",
    141                          (long) fail_size);
    142         }
    143 
    144       if (_dbus_getenv ("DBUS_MALLOC_GUARDS") != NULL)
    145         {
    146           guards = TRUE;
    147           _dbus_verbose ("Will use malloc guards\n");
    148         }
    149 
    150       if (_dbus_getenv ("DBUS_DISABLE_MEM_POOLS") != NULL)
    151         {
    152           disable_mem_pools = TRUE;
    153           _dbus_verbose ("Will disable memory pools\n");
    154         }
    155 
    156       if (_dbus_getenv ("DBUS_MALLOC_BACKTRACES") != NULL)
    157         {
    158           backtrace_on_fail_alloc = TRUE;
    159           _dbus_verbose ("Will backtrace on failing a malloc\n");
    160         }
    161     }
    162 }
    163 
    164 /**
    165  * Whether to turn off mem pools, useful for leak checking.
    166  *
    167  * @returns #TRUE if mempools should not be used.
    168  */
    169 dbus_bool_t
    170 _dbus_disable_mem_pools (void)
    171 {
    172   _dbus_initialize_malloc_debug ();
    173   return disable_mem_pools;
    174 }
    175 
    176 /**
    177  * Sets the number of allocations until we simulate a failed
    178  * allocation. If set to 0, the next allocation to run
    179  * fails; if set to 1, one succeeds then the next fails; etc.
    180  * Set to _DBUS_INT_MAX to not fail anything.
    181  *
    182  * @param until_next_fail number of successful allocs before one fails
    183  */
    184 void
    185 _dbus_set_fail_alloc_counter (int until_next_fail)
    186 {
    187   _dbus_initialize_malloc_debug ();
    188 
    189   fail_alloc_counter = until_next_fail;
    190 
    191 #if 0
    192   _dbus_verbose ("Set fail alloc counter = %d\n", fail_alloc_counter);
    193 #endif
    194 }
    195 
    196 /**
    197  * Gets the number of successful allocs until we'll simulate
    198  * a failed alloc.
    199  *
    200  * @returns current counter value
    201  */
    202 int
    203 _dbus_get_fail_alloc_counter (void)
    204 {
    205   _dbus_initialize_malloc_debug ();
    206 
    207   return fail_alloc_counter;
    208 }
    209 
    210 /**
    211  * Sets how many mallocs to fail when the fail alloc counter reaches
    212  * 0.
    213  *
    214  * @param failures_per_failure number to fail
    215  */
    216 void
    217 _dbus_set_fail_alloc_failures (int failures_per_failure)
    218 {
    219   n_failures_per_failure = failures_per_failure;
    220 }
    221 
    222 /**
    223  * Gets the number of failures we'll have when the fail malloc
    224  * counter reaches 0.
    225  *
    226  * @returns number of failures planned
    227  */
    228 int
    229 _dbus_get_fail_alloc_failures (void)
    230 {
    231   return n_failures_per_failure;
    232 }
    233 
    234 #ifdef DBUS_BUILD_TESTS
    235 /**
    236  * Called when about to alloc some memory; if
    237  * it returns #TRUE, then the allocation should
    238  * fail. If it returns #FALSE, then the allocation
    239  * should not fail.
    240  *
    241  * @returns #TRUE if this alloc should fail
    242  */
    243 dbus_bool_t
    244 _dbus_decrement_fail_alloc_counter (void)
    245 {
    246   _dbus_initialize_malloc_debug ();
    247 
    248   if (fail_alloc_counter <= 0)
    249     {
    250       if (backtrace_on_fail_alloc)
    251         _dbus_print_backtrace ();
    252 
    253       _dbus_verbose ("failure %d\n", n_failures_this_failure);
    254 
    255       n_failures_this_failure += 1;
    256       if (n_failures_this_failure >= n_failures_per_failure)
    257         {
    258           if (fail_nth >= 0)
    259             fail_alloc_counter = fail_nth;
    260           else
    261             fail_alloc_counter = _DBUS_INT_MAX;
    262 
    263           n_failures_this_failure = 0;
    264 
    265           _dbus_verbose ("reset fail alloc counter to %d\n", fail_alloc_counter);
    266         }
    267 
    268       return TRUE;
    269     }
    270   else
    271     {
    272       fail_alloc_counter -= 1;
    273       return FALSE;
    274     }
    275 }
    276 #endif /* DBUS_BUILD_TESTS */
    277 
    278 /**
    279  * Get the number of outstanding malloc()'d blocks.
    280  *
    281  * @returns number of blocks
    282  */
    283 int
    284 _dbus_get_malloc_blocks_outstanding (void)
    285 {
    286   return n_blocks_outstanding.value;
    287 }
    288 
    289 /**
    290  * Where the block came from.
    291  */
    292 typedef enum
    293 {
    294   SOURCE_UNKNOWN,
    295   SOURCE_MALLOC,
    296   SOURCE_REALLOC,
    297   SOURCE_MALLOC_ZERO,
    298   SOURCE_REALLOC_NULL
    299 } BlockSource;
    300 
    301 static const char*
    302 source_string (BlockSource source)
    303 {
    304   switch (source)
    305     {
    306     case SOURCE_UNKNOWN:
    307       return "unknown";
    308     case SOURCE_MALLOC:
    309       return "malloc";
    310     case SOURCE_REALLOC:
    311       return "realloc";
    312     case SOURCE_MALLOC_ZERO:
    313       return "malloc0";
    314     case SOURCE_REALLOC_NULL:
    315       return "realloc(NULL)";
    316     }
    317   _dbus_assert_not_reached ("Invalid malloc block source ID");
    318   return "invalid!";
    319 }
    320 
    321 static void
    322 check_guards (void       *free_block,
    323               dbus_bool_t overwrite)
    324 {
    325   if (free_block != NULL)
    326     {
    327       unsigned char *block = ((unsigned char*)free_block) - GUARD_START_OFFSET;
    328       size_t requested_bytes = *(dbus_uint32_t*)block;
    329       BlockSource source = *(dbus_uint32_t*)(block + 4);
    330       unsigned int i;
    331       dbus_bool_t failed;
    332 
    333       failed = FALSE;
    334 
    335 #if 0
    336       _dbus_verbose ("Checking %d bytes request from source %s\n",
    337                      requested_bytes, source_string (source));
    338 #endif
    339 
    340       i = GUARD_INFO_SIZE;
    341       while (i < GUARD_START_OFFSET)
    342         {
    343           dbus_uint32_t value = *(dbus_uint32_t*) &block[i];
    344           if (value != GUARD_VALUE)
    345             {
    346               _dbus_warn ("Block of %lu bytes from %s had start guard value 0x%ux at %d expected 0x%x\n",
    347                           (long) requested_bytes, source_string (source),
    348                           value, i, GUARD_VALUE);
    349               failed = TRUE;
    350             }
    351 
    352           i += 4;
    353         }
    354 
    355       i = GUARD_START_OFFSET + requested_bytes;
    356       while (i < (GUARD_START_OFFSET + requested_bytes + GUARD_END_PAD))
    357         {
    358           dbus_uint32_t value = *(dbus_uint32_t*) &block[i];
    359           if (value != GUARD_VALUE)
    360             {
    361               _dbus_warn ("Block of %lu bytes from %s had end guard value 0x%ux at %d expected 0x%x\n",
    362                           (long) requested_bytes, source_string (source),
    363                           value, i, GUARD_VALUE);
    364               failed = TRUE;
    365             }
    366 
    367           i += 4;
    368         }
    369 
    370       /* set memory to anything but nul bytes */
    371       if (overwrite)
    372         memset (free_block, 'g', requested_bytes);
    373 
    374       if (failed)
    375         _dbus_assert_not_reached ("guard value corruption");
    376     }
    377 }
    378 
    379 static void*
    380 set_guards (void       *real_block,
    381             size_t      requested_bytes,
    382             BlockSource source)
    383 {
    384   unsigned char *block = real_block;
    385   unsigned int i;
    386 
    387   if (block == NULL)
    388     return NULL;
    389 
    390   _dbus_assert (GUARD_START_OFFSET + GUARD_END_PAD == GUARD_EXTRA_SIZE);
    391 
    392   *((dbus_uint32_t*)block) = requested_bytes;
    393   *((dbus_uint32_t*)(block + 4)) = source;
    394 
    395   i = GUARD_INFO_SIZE;
    396   while (i < GUARD_START_OFFSET)
    397     {
    398       (*(dbus_uint32_t*) &block[i]) = GUARD_VALUE;
    399 
    400       i += 4;
    401     }
    402 
    403   i = GUARD_START_OFFSET + requested_bytes;
    404   while (i < (GUARD_START_OFFSET + requested_bytes + GUARD_END_PAD))
    405     {
    406       (*(dbus_uint32_t*) &block[i]) = GUARD_VALUE;
    407 
    408       i += 4;
    409     }
    410 
    411   check_guards (block + GUARD_START_OFFSET, FALSE);
    412 
    413   return block + GUARD_START_OFFSET;
    414 }
    415 
    416 #endif
    417 
    418 /** @} */ /* End of internals docs */
    419 
    420 
    421 /**
    422  * @addtogroup DBusMemory
    423  *
    424  * @{
    425  */
    426 
    427 /**
    428  * Allocates the given number of bytes, as with standard
    429  * malloc(). Guaranteed to return #NULL if bytes is zero
    430  * on all platforms. Returns #NULL if the allocation fails.
    431  * The memory must be released with dbus_free().
    432  *
    433  * dbus_malloc() memory is NOT safe to free with regular free() from
    434  * the C library. Free it with dbus_free() only.
    435  *
    436  * @param bytes number of bytes to allocate
    437  * @return allocated memory, or #NULL if the allocation fails.
    438  */
    439 void*
    440 dbus_malloc (size_t bytes)
    441 {
    442 #ifdef DBUS_BUILD_TESTS
    443   _dbus_initialize_malloc_debug ();
    444 
    445   if (_dbus_decrement_fail_alloc_counter ())
    446     {
    447       _dbus_verbose (" FAILING malloc of %ld bytes\n", (long) bytes);
    448       return NULL;
    449     }
    450 #endif
    451 
    452   if (bytes == 0) /* some system mallocs handle this, some don't */
    453     return NULL;
    454 #ifdef DBUS_BUILD_TESTS
    455   else if (fail_size != 0 && bytes > fail_size)
    456     return NULL;
    457   else if (guards)
    458     {
    459       void *block;
    460 
    461       block = malloc (bytes + GUARD_EXTRA_SIZE);
    462       if (block)
    463 	_dbus_atomic_inc (&n_blocks_outstanding);
    464 
    465       return set_guards (block, bytes, SOURCE_MALLOC);
    466     }
    467 #endif
    468   else
    469     {
    470       void *mem;
    471       mem = malloc (bytes);
    472 #ifdef DBUS_BUILD_TESTS
    473       if (mem)
    474 	_dbus_atomic_inc (&n_blocks_outstanding);
    475 #endif
    476       return mem;
    477     }
    478 }
    479 
    480 /**
    481  * Allocates the given number of bytes, as with standard malloc(), but
    482  * all bytes are initialized to zero as with calloc(). Guaranteed to
    483  * return #NULL if bytes is zero on all platforms. Returns #NULL if the
    484  * allocation fails.  The memory must be released with dbus_free().
    485  *
    486  * dbus_malloc0() memory is NOT safe to free with regular free() from
    487  * the C library. Free it with dbus_free() only.
    488  *
    489  * @param bytes number of bytes to allocate
    490  * @return allocated memory, or #NULL if the allocation fails.
    491  */
    492 void*
    493 dbus_malloc0 (size_t bytes)
    494 {
    495 #ifdef DBUS_BUILD_TESTS
    496   _dbus_initialize_malloc_debug ();
    497 
    498   if (_dbus_decrement_fail_alloc_counter ())
    499     {
    500       _dbus_verbose (" FAILING malloc0 of %ld bytes\n", (long) bytes);
    501 
    502       return NULL;
    503     }
    504 #endif
    505 
    506   if (bytes == 0)
    507     return NULL;
    508 #ifdef DBUS_BUILD_TESTS
    509   else if (fail_size != 0 && bytes > fail_size)
    510     return NULL;
    511   else if (guards)
    512     {
    513       void *block;
    514 
    515       block = calloc (bytes + GUARD_EXTRA_SIZE, 1);
    516       if (block)
    517 	_dbus_atomic_inc (&n_blocks_outstanding);
    518       return set_guards (block, bytes, SOURCE_MALLOC_ZERO);
    519     }
    520 #endif
    521   else
    522     {
    523       void *mem;
    524       mem = calloc (bytes, 1);
    525 #ifdef DBUS_BUILD_TESTS
    526       if (mem)
    527 	_dbus_atomic_inc (&n_blocks_outstanding);
    528 #endif
    529       return mem;
    530     }
    531 }
    532 
    533 /**
    534  * Resizes a block of memory previously allocated by dbus_malloc() or
    535  * dbus_malloc0(). Guaranteed to free the memory and return #NULL if bytes
    536  * is zero on all platforms. Returns #NULL if the resize fails.
    537  * If the resize fails, the memory is not freed.
    538  *
    539  * @param memory block to be resized
    540  * @param bytes new size of the memory block
    541  * @return allocated memory, or #NULL if the resize fails.
    542  */
    543 void*
    544 dbus_realloc (void  *memory,
    545               size_t bytes)
    546 {
    547 #ifdef DBUS_BUILD_TESTS
    548   _dbus_initialize_malloc_debug ();
    549 
    550   if (_dbus_decrement_fail_alloc_counter ())
    551     {
    552       _dbus_verbose (" FAILING realloc of %ld bytes\n", (long) bytes);
    553 
    554       return NULL;
    555     }
    556 #endif
    557 
    558   if (bytes == 0) /* guarantee this is safe */
    559     {
    560       dbus_free (memory);
    561       return NULL;
    562     }
    563 #ifdef DBUS_BUILD_TESTS
    564   else if (fail_size != 0 && bytes > fail_size)
    565     return NULL;
    566   else if (guards)
    567     {
    568       if (memory)
    569         {
    570           size_t old_bytes;
    571           void *block;
    572 
    573           check_guards (memory, FALSE);
    574 
    575           block = realloc (((unsigned char*)memory) - GUARD_START_OFFSET,
    576                            bytes + GUARD_EXTRA_SIZE);
    577 
    578 	  old_bytes = *(dbus_uint32_t*)block;
    579           if (block && bytes >= old_bytes)
    580             /* old guards shouldn't have moved */
    581             check_guards (((unsigned char*)block) + GUARD_START_OFFSET, FALSE);
    582 
    583           return set_guards (block, bytes, SOURCE_REALLOC);
    584         }
    585       else
    586         {
    587           void *block;
    588 
    589           block = malloc (bytes + GUARD_EXTRA_SIZE);
    590 
    591           if (block)
    592 	    _dbus_atomic_inc (&n_blocks_outstanding);
    593 
    594           return set_guards (block, bytes, SOURCE_REALLOC_NULL);
    595         }
    596     }
    597 #endif
    598   else
    599     {
    600       void *mem;
    601       mem = realloc (memory, bytes);
    602 #ifdef DBUS_BUILD_TESTS
    603       if (memory == NULL && mem != NULL)
    604 	    _dbus_atomic_inc (&n_blocks_outstanding);
    605 #endif
    606       return mem;
    607     }
    608 }
    609 
    610 /**
    611  * Frees a block of memory previously allocated by dbus_malloc() or
    612  * dbus_malloc0(). If passed #NULL, does nothing.
    613  *
    614  * @param memory block to be freed
    615  */
    616 void
    617 dbus_free (void  *memory)
    618 {
    619 #ifdef DBUS_BUILD_TESTS
    620   if (guards)
    621     {
    622       check_guards (memory, TRUE);
    623       if (memory)
    624         {
    625 	  _dbus_atomic_dec (&n_blocks_outstanding);
    626 
    627 	  _dbus_assert (n_blocks_outstanding.value >= 0);
    628 
    629           free (((unsigned char*)memory) - GUARD_START_OFFSET);
    630         }
    631 
    632       return;
    633     }
    634 #endif
    635 
    636   if (memory) /* we guarantee it's safe to free (NULL) */
    637     {
    638 #ifdef DBUS_BUILD_TESTS
    639       _dbus_atomic_dec (&n_blocks_outstanding);
    640 
    641       _dbus_assert (n_blocks_outstanding.value >= 0);
    642 #endif
    643 
    644       free (memory);
    645     }
    646 }
    647 
    648 /**
    649  * Frees a #NULL-terminated array of strings.
    650  * If passed #NULL, does nothing.
    651  *
    652  * @param str_array the array to be freed
    653  */
    654 void
    655 dbus_free_string_array (char **str_array)
    656 {
    657   if (str_array)
    658     {
    659       int i;
    660 
    661       i = 0;
    662       while (str_array[i])
    663 	{
    664 	  dbus_free (str_array[i]);
    665 	  i++;
    666 	}
    667 
    668       dbus_free (str_array);
    669     }
    670 }
    671 
    672 /** @} */ /* End of public API docs block */
    673 
    674 
    675 /**
    676  * @addtogroup DBusMemoryInternals
    677  *
    678  * @{
    679  */
    680 
    681 /**
    682  * _dbus_current_generation is used to track each
    683  * time that dbus_shutdown() is called, so we can
    684  * reinit things after it's been called. It is simply
    685  * incremented each time we shut down.
    686  */
    687 int _dbus_current_generation = 1;
    688 
    689 /**
    690  * Represents a function to be called on shutdown.
    691  */
    692 typedef struct ShutdownClosure ShutdownClosure;
    693 
    694 /**
    695  * This struct represents a function to be called on shutdown.
    696  */
    697 struct ShutdownClosure
    698 {
    699   ShutdownClosure *next;     /**< Next ShutdownClosure */
    700   DBusShutdownFunction func; /**< Function to call */
    701   void *data;                /**< Data for function */
    702 };
    703 
    704 _DBUS_DEFINE_GLOBAL_LOCK (shutdown_funcs);
    705 static ShutdownClosure *registered_globals = NULL;
    706 
    707 /**
    708  * Register a cleanup function to be called exactly once
    709  * the next time dbus_shutdown() is called.
    710  *
    711  * @param func the function
    712  * @param data data to pass to the function
    713  * @returns #FALSE on not enough memory
    714  */
    715 dbus_bool_t
    716 _dbus_register_shutdown_func (DBusShutdownFunction  func,
    717                               void                 *data)
    718 {
    719   ShutdownClosure *c;
    720 
    721   c = dbus_new (ShutdownClosure, 1);
    722 
    723   if (c == NULL)
    724     return FALSE;
    725 
    726   c->func = func;
    727   c->data = data;
    728 
    729   _DBUS_LOCK (shutdown_funcs);
    730 
    731   c->next = registered_globals;
    732   registered_globals = c;
    733 
    734   _DBUS_UNLOCK (shutdown_funcs);
    735 
    736   return TRUE;
    737 }
    738 
    739 /** @} */ /* End of private API docs block */
    740 
    741 
    742 /**
    743  * @addtogroup DBusMemory
    744  *
    745  * @{
    746  */
    747 
    748 /**
    749  * Frees all memory allocated internally by libdbus and
    750  * reverses the effects of dbus_threads_init(). libdbus keeps internal
    751  * global variables, for example caches and thread locks, and it
    752  * can be useful to free these internal data structures.
    753  *
    754  * dbus_shutdown() does NOT free memory that was returned
    755  * to the application. It only returns libdbus-internal
    756  * data structures.
    757  *
    758  * You MUST free all memory and release all reference counts
    759  * returned to you by libdbus prior to calling dbus_shutdown().
    760  *
    761  * You can't continue to use any D-Bus objects, such as connections,
    762  * that were allocated prior to dbus_shutdown(). You can, however,
    763  * start over; call dbus_threads_init() again, create new connections,
    764  * and so forth.
    765  *
    766  * WARNING: dbus_shutdown() is NOT thread safe, it must be called
    767  * while NO other threads are using D-Bus. (Remember, you have to free
    768  * all D-Bus objects and memory before you call dbus_shutdown(), so no
    769  * thread can be using libdbus.)
    770  *
    771  * The purpose of dbus_shutdown() is to allow applications to get
    772  * clean output from memory leak checkers. dbus_shutdown() may also be
    773  * useful if you want to dlopen() libdbus instead of linking to it,
    774  * and want to be able to unload the library again.
    775  *
    776  * There is absolutely no requirement to call dbus_shutdown() - in fact,
    777  * most applications won't bother and should not feel guilty.
    778  *
    779  * You have to know that nobody is using libdbus in your application's
    780  * process before you can call dbus_shutdown(). One implication of this
    781  * is that calling dbus_shutdown() from a library is almost certainly
    782  * wrong, since you don't know what the rest of the app is up to.
    783  *
    784  */
    785 void
    786 dbus_shutdown (void)
    787 {
    788   while (registered_globals != NULL)
    789     {
    790       ShutdownClosure *c;
    791 
    792       c = registered_globals;
    793       registered_globals = c->next;
    794 
    795       (* c->func) (c->data);
    796 
    797       dbus_free (c);
    798     }
    799 
    800   _dbus_current_generation += 1;
    801 }
    802 
    803 /** @} */ /** End of public API docs block */
    804 
    805 #ifdef DBUS_BUILD_TESTS
    806 #include "dbus-test.h"
    807 
    808 /**
    809  * @ingroup DBusMemoryInternals
    810  * Unit test for DBusMemory
    811  * @returns #TRUE on success.
    812  */
    813 dbus_bool_t
    814 _dbus_memory_test (void)
    815 {
    816   dbus_bool_t old_guards;
    817   void *p;
    818   size_t size;
    819 
    820   old_guards = guards;
    821   guards = TRUE;
    822   p = dbus_malloc (4);
    823   if (p == NULL)
    824     _dbus_assert_not_reached ("no memory");
    825   for (size = 4; size < 256; size += 4)
    826     {
    827       p = dbus_realloc (p, size);
    828       if (p == NULL)
    829 	_dbus_assert_not_reached ("no memory");
    830     }
    831   for (size = 256; size != 0; size -= 4)
    832     {
    833       p = dbus_realloc (p, size);
    834       if (p == NULL)
    835 	_dbus_assert_not_reached ("no memory");
    836     }
    837   dbus_free (p);
    838   guards = old_guards;
    839   return TRUE;
    840 }
    841 
    842 #endif
    843