Coverage report for dbus/dbus-memory.c.gcov

        -:    0:Source:dbus-memory.c
        -:    0:Graph:.libs/dbus-memory.gcno
        -:    0:Data:.libs/dbus-memory.gcda
        -:    0:Runs:11815
        -:    0:Programs:5
        -:    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 int 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)
function _dbus_initialize_malloc_debug called 72314173 returned 100% blocks executed 57%
 72314173:  125:{
 72314173:  126:  if (!debug_initialized)
branch  0 taken 1% (fallthrough)
branch  1 taken 99%
        -:  127:    {
      938:  128:      debug_initialized = TRUE;
        -:  129:      
      938:  130:      if (_dbus_getenv ("DBUS_MALLOC_FAIL_NTH") != NULL)
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -:  131:	{
    #####:  132:	  fail_nth = atoi (_dbus_getenv ("DBUS_MALLOC_FAIL_NTH"));
call    0 never executed
call    1 never executed
    #####:  133:          fail_alloc_counter = fail_nth;
    #####:  134:          _dbus_verbose ("Will fail malloc every %d times\n", fail_nth);
call    0 never executed
        -:  135:	}
        -:  136:      
      938:  137:      if (_dbus_getenv ("DBUS_MALLOC_FAIL_GREATER_THAN") != NULL)
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -:  138:        {
    #####:  139:          fail_size = atoi (_dbus_getenv ("DBUS_MALLOC_FAIL_GREATER_THAN"));
call    0 never executed
call    1 never executed
    #####:  140:          _dbus_verbose ("Will fail mallocs over %ld bytes\n",
call    0 never executed
        -:  141:                         (long) fail_size);
        -:  142:        }
        -:  143:
      938:  144:      if (_dbus_getenv ("DBUS_MALLOC_GUARDS") != NULL)
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -:  145:        {
    #####:  146:          guards = TRUE;
    #####:  147:          _dbus_verbose ("Will use malloc guards\n");
call    0 never executed
        -:  148:        }
        -:  149:
      938:  150:      if (_dbus_getenv ("DBUS_DISABLE_MEM_POOLS") != NULL)
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -:  151:        {
    #####:  152:          disable_mem_pools = TRUE;
    #####:  153:          _dbus_verbose ("Will disable memory pools\n");
call    0 never executed
        -:  154:        }
        -:  155:
      938:  156:      if (_dbus_getenv ("DBUS_MALLOC_BACKTRACES") != NULL)
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -:  157:        {
    #####:  158:          backtrace_on_fail_alloc = TRUE;
    #####:  159:          _dbus_verbose ("Will backtrace on failing a malloc\n");
call    0 never executed
        -:  160:        }
        -:  161:    }
 72314173:  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)
function _dbus_disable_mem_pools called 11546249 returned 100% blocks executed 100%
 11546249:  171:{
 11546249:  172:  _dbus_initialize_malloc_debug ();
call    0 returned 100%
 11546249:  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)
function _dbus_set_fail_alloc_counter called 2945181 returned 100% blocks executed 100%
  2945181:  186:{
  2945181:  187:  _dbus_initialize_malloc_debug ();
call    0 returned 100%
        -:  188:
  2945181:  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
  2945181:  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)
function _dbus_get_fail_alloc_counter called 2931024 returned 100% blocks executed 100%
  2931024:  204:{
  2931024:  205:  _dbus_initialize_malloc_debug ();
call    0 returned 100%
        -:  206:
  2931024:  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)
function _dbus_set_fail_alloc_failures called 58 returned 100% blocks executed 100%
       58:  218:{
       58:  219:  n_failures_per_failure = failures_per_failure;
       58:  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)
function _dbus_get_fail_alloc_failures called 14100 returned 100% blocks executed 100%
    14100:  230:{
    14100:  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)
function _dbus_decrement_fail_alloc_counter called 30335497 returned 100% blocks executed 85%
 30335497:  245:{
 30335497:  246:  _dbus_initialize_malloc_debug ();
call    0 returned 100%
        -:  247:  
 30335497:  248:  if (fail_alloc_counter <= 0)
branch  0 taken 1% (fallthrough)
branch  1 taken 99%
        -:  249:    {
    25341:  250:      if (backtrace_on_fail_alloc)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
    #####:  251:        _dbus_print_backtrace ();
call    0 never executed
        -:  252:
    25341:  253:      _dbus_verbose ("failure %d\n", n_failures_this_failure);
call    0 returned 100%
        -:  254:      
    25341:  255:      n_failures_this_failure += 1;
    25341:  256:      if (n_failures_this_failure >= n_failures_per_failure)
branch  0 taken 51% (fallthrough)
branch  1 taken 49%
        -:  257:        {
    12841:  258:          if (fail_nth >= 0)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
    #####:  259:            fail_alloc_counter = fail_nth;
        -:  260:          else
    12841:  261:            fail_alloc_counter = _DBUS_INT_MAX;
        -:  262:
    12841:  263:          n_failures_this_failure = 0;
        -:  264:
    12841:  265:          _dbus_verbose ("reset fail alloc counter to %d\n", fail_alloc_counter);
call    0 returned 100%
        -:  266:        }
        -:  267:      
    25341:  268:      return TRUE;
        -:  269:    }
        -:  270:  else
        -:  271:    {
 30310156:  272:      fail_alloc_counter -= 1;
 30310156:  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)
function _dbus_get_malloc_blocks_outstanding called 34 returned 100% blocks executed 100%
       34:  285:{
       34:  286:  return n_blocks_outstanding;
        -:  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)
function source_string called 0 returned 0% blocks executed 0%
    #####:  303:{
    #####:  304:  switch (source)
branch  0 never executed
branch  1 never executed
branch  2 never executed
branch  3 never executed
branch  4 never executed
branch  5 never executed
        -:  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");
call    0 never executed
        -:  318:  return "invalid!";
        -:  319:}
        -:  320:
        -:  321:static void
        -:  322:check_guards (void       *free_block,
        -:  323:              dbus_bool_t overwrite)
function check_guards called 320 returned 100% blocks executed 65%
      320:  324:{
      320:  325:  if (free_block != NULL)
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
        -:  326:    {
      320:  327:      unsigned char *block = ((unsigned char*)free_block) - GUARD_START_OFFSET;
      320:  328:      size_t requested_bytes = *(dbus_uint32_t*)block;
      320:  329:      BlockSource source = *(dbus_uint32_t*)(block + 4);
        -:  330:      unsigned int i;
        -:  331:      dbus_bool_t failed;
        -:  332:
      320:  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:      
      320:  340:      i = GUARD_INFO_SIZE;
     1920:  341:      while (i < GUARD_START_OFFSET)
branch  0 taken 80%
branch  1 taken 20% (fallthrough)
        -:  342:        {
     1280:  343:          dbus_uint32_t value = *(dbus_uint32_t*) &block[i];
     1280:  344:          if (value != GUARD_VALUE)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -:  345:            {
    #####:  346:              _dbus_warn ("Block of %lu bytes from %s had start guard value 0x%ux at %d expected 0x%x\n",
call    0 never executed
call    1 never executed
        -:  347:                          (long) requested_bytes, source_string (source),
        -:  348:                          value, i, GUARD_VALUE);
    #####:  349:              failed = TRUE;
        -:  350:            }
        -:  351:          
     1280:  352:          i += 4;
        -:  353:        }
        -:  354:
      320:  355:      i = GUARD_START_OFFSET + requested_bytes;
     1920:  356:      while (i < (GUARD_START_OFFSET + requested_bytes + GUARD_END_PAD))
branch  0 taken 80%
branch  1 taken 20% (fallthrough)
        -:  357:        {
     1280:  358:          dbus_uint32_t value = *(dbus_uint32_t*) &block[i];
     1280:  359:          if (value != GUARD_VALUE)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -:  360:            {
    #####:  361:              _dbus_warn ("Block of %lu bytes from %s had end guard value 0x%ux at %d expected 0x%x\n",
call    0 never executed
call    1 never executed
        -:  362:                          (long) requested_bytes, source_string (source),
        -:  363:                          value, i, GUARD_VALUE);
    #####:  364:              failed = TRUE;
        -:  365:            }
        -:  366:          
     1280:  367:          i += 4;
        -:  368:        }
        -:  369:
        -:  370:      /* set memory to anything but nul bytes */
      320:  371:      if (overwrite)
branch  0 taken 1% (fallthrough)
branch  1 taken 99%
        1:  372:        memset (free_block, 'g', requested_bytes);
call    0 returned 100%
        -:  373:      
      320:  374:      if (failed)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
    #####:  375:        _dbus_assert_not_reached ("guard value corruption");
call    0 never executed
        -:  376:    }
      320:  377:}
        -:  378:
        -:  379:static void*
        -:  380:set_guards (void       *real_block,
        -:  381:            size_t      requested_bytes,
        -:  382:            BlockSource source)
function set_guards called 128 returned 100% blocks executed 92%
      128:  383:{
      128:  384:  unsigned char *block = real_block;
        -:  385:  unsigned int i;
        -:  386:  
      128:  387:  if (block == NULL)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
    #####:  388:    return NULL;
        -:  389:
      128:  390:  _dbus_assert (GUARD_START_OFFSET + GUARD_END_PAD == GUARD_EXTRA_SIZE);
call    0 returned 100%
        -:  391:  
      128:  392:  *((dbus_uint32_t*)block) = requested_bytes;
      128:  393:  *((dbus_uint32_t*)(block + 4)) = source;
        -:  394:
      128:  395:  i = GUARD_INFO_SIZE;
      768:  396:  while (i < GUARD_START_OFFSET)
branch  0 taken 80%
branch  1 taken 20% (fallthrough)
        -:  397:    {
      512:  398:      (*(dbus_uint32_t*) &block[i]) = GUARD_VALUE;
        -:  399:      
      512:  400:      i += 4;
        -:  401:    }
        -:  402:
      128:  403:  i = GUARD_START_OFFSET + requested_bytes;
      768:  404:  while (i < (GUARD_START_OFFSET + requested_bytes + GUARD_END_PAD))
branch  0 taken 80%
branch  1 taken 20% (fallthrough)
        -:  405:    {
      512:  406:      (*(dbus_uint32_t*) &block[i]) = GUARD_VALUE;
        -:  407:      
      512:  408:      i += 4;
        -:  409:    }
        -:  410:  
      128:  411:  check_guards (block + GUARD_START_OFFSET, FALSE);
call    0 returned 100%
        -:  412:  
      128:  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: * @param bytes number of bytes to allocate
        -:  434: * @return allocated memory, or #NULL if the allocation fails.
        -:  435: */
        -:  436:void*
        -:  437:dbus_malloc (size_t bytes)
function dbus_malloc called 3617253 returned 100% blocks executed 86%
  3617253:  438:{
        -:  439:#ifdef DBUS_BUILD_TESTS
  3617253:  440:  _dbus_initialize_malloc_debug ();
call    0 returned 100%
        -:  441:  
  3617253:  442:  if (_dbus_decrement_fail_alloc_counter ())
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
        -:  443:    {
     7512:  444:      _dbus_verbose (" FAILING malloc of %ld bytes\n", (long) bytes);
call    0 returned 100%
        -:  445:      
     7512:  446:      return NULL;
        -:  447:    }
        -:  448:#endif
        -:  449:  
  3609741:  450:  if (bytes == 0) /* some system mallocs handle this, some don't */
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
    #####:  451:    return NULL;
        -:  452:#ifdef DBUS_BUILD_TESTS
  3609741:  453:  else if (fail_size != 0 && bytes > fail_size)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
branch  2 never executed
branch  3 never executed
    #####:  454:    return NULL;
  3609741:  455:  else if (guards)
branch  0 taken 1% (fallthrough)
branch  1 taken 99%
        -:  456:    {
        -:  457:      void *block;
        -:  458:
        1:  459:      block = malloc (bytes + GUARD_EXTRA_SIZE);
call    0 returned 100%
        1:  460:      if (block)
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
        1:  461:        n_blocks_outstanding += 1;
        -:  462:      
        1:  463:      return set_guards (block, bytes, SOURCE_MALLOC);
call    0 returned 100%
        -:  464:    }
        -:  465:#endif
        -:  466:  else
        -:  467:    {
        -:  468:      void *mem;
  3609740:  469:      mem = malloc (bytes);
call    0 returned 100%
        -:  470:#ifdef DBUS_BUILD_TESTS
  3609740:  471:      if (mem)
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
  3609740:  472:        n_blocks_outstanding += 1;
        -:  473:#endif
  3609740:  474:      return mem;
        -:  475:    }
        -:  476:}
        -:  477:
        -:  478:/**
        -:  479: * Allocates the given number of bytes, as with standard malloc(), but
        -:  480: * all bytes are initialized to zero as with calloc(). Guaranteed to
        -:  481: * return #NULL if bytes is zero on all platforms. Returns #NULL if the
        -:  482: * allocation fails.  The memory must be released with dbus_free().
        -:  483: *
        -:  484: * @param bytes number of bytes to allocate
        -:  485: * @return allocated memory, or #NULL if the allocation fails.
        -:  486: */
        -:  487:void*
        -:  488:dbus_malloc0 (size_t bytes)
function dbus_malloc0 called 4843963 returned 100% blocks executed 62%
  4843963:  489:{
        -:  490:#ifdef DBUS_BUILD_TESTS
  4843963:  491:  _dbus_initialize_malloc_debug ();
call    0 returned 100%
        -:  492:  
  4843963:  493:  if (_dbus_decrement_fail_alloc_counter ())
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
        -:  494:    {
     2872:  495:      _dbus_verbose (" FAILING malloc0 of %ld bytes\n", (long) bytes);
call    0 returned 100%
        -:  496:      
     2872:  497:      return NULL;
        -:  498:    }
        -:  499:#endif
        -:  500:
  4841091:  501:  if (bytes == 0)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
    #####:  502:    return NULL;
        -:  503:#ifdef DBUS_BUILD_TESTS
  4841091:  504:  else if (fail_size != 0 && bytes > fail_size)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
branch  2 never executed
branch  3 never executed
    #####:  505:    return NULL;
  4841091:  506:  else if (guards)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -:  507:    {
        -:  508:      void *block;
        -:  509:
    #####:  510:      block = calloc (bytes + GUARD_EXTRA_SIZE, 1);
call    0 never executed
    #####:  511:      if (block)
branch  0 never executed
branch  1 never executed
    #####:  512:        n_blocks_outstanding += 1;
    #####:  513:      return set_guards (block, bytes, SOURCE_MALLOC_ZERO);
call    0 never executed
        -:  514:    }
        -:  515:#endif
        -:  516:  else
        -:  517:    {
        -:  518:      void *mem;
  4841091:  519:      mem = calloc (bytes, 1);
call    0 returned 100%
        -:  520:#ifdef DBUS_BUILD_TESTS
  4841091:  521:      if (mem)
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
  4841091:  522:        n_blocks_outstanding += 1;
        -:  523:#endif
  4841091:  524:      return mem;
        -:  525:    }
        -:  526:}
        -:  527:
        -:  528:/**
        -:  529: * Resizes a block of memory previously allocated by dbus_malloc() or
        -:  530: * dbus_malloc0(). Guaranteed to free the memory and return #NULL if bytes
        -:  531: * is zero on all platforms. Returns #NULL if the resize fails.
        -:  532: * If the resize fails, the memory is not freed.
        -:  533: *
        -:  534: * @param memory block to be resized
        -:  535: * @param bytes new size of the memory block
        -:  536: * @return allocated memory, or #NULL if the resize fails.
        -:  537: */
        -:  538:void*
        -:  539:dbus_realloc (void  *memory,
        -:  540:              size_t bytes)
function dbus_realloc called 16095006 returned 100% blocks executed 71%
 16095006:  541:{
        -:  542:#ifdef DBUS_BUILD_TESTS
 16095006:  543:  _dbus_initialize_malloc_debug ();
call    0 returned 100%
        -:  544:  
 16095006:  545:  if (_dbus_decrement_fail_alloc_counter ())
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
        -:  546:    {
     7732:  547:      _dbus_verbose (" FAILING realloc of %ld bytes\n", (long) bytes);
call    0 returned 100%
        -:  548:      
     7732:  549:      return NULL;
        -:  550:    }
        -:  551:#endif
        -:  552:  
 16087274:  553:  if (bytes == 0) /* guarantee this is safe */
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -:  554:    {
    #####:  555:      dbus_free (memory);
call    0 never executed
    #####:  556:      return NULL;
        -:  557:    }
        -:  558:#ifdef DBUS_BUILD_TESTS
 16087274:  559:  else if (fail_size != 0 && bytes > fail_size)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
branch  2 never executed
branch  3 never executed
    #####:  560:    return NULL;
 16087274:  561:  else if (guards)
branch  0 taken 1% (fallthrough)
branch  1 taken 99%
        -:  562:    {
      127:  563:      if (memory)
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
        -:  564:        {
        -:  565:          size_t old_bytes;
        -:  566:          void *block;
        -:  567:          
      127:  568:          check_guards (memory, FALSE);
call    0 returned 100%
        -:  569:          
      127:  570:          block = realloc (((unsigned char*)memory) - GUARD_START_OFFSET,
call    0 returned 100%
        -:  571:                           bytes + GUARD_EXTRA_SIZE);
        -:  572:
      127:  573:	  old_bytes = *(dbus_uint32_t*)block;
      127:  574:          if (block && bytes >= old_bytes)
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
branch  2 taken 50% (fallthrough)
branch  3 taken 50%
        -:  575:            /* old guards shouldn't have moved */
       64:  576:            check_guards (((unsigned char*)block) + GUARD_START_OFFSET, FALSE);
call    0 returned 100%
        -:  577:          
      127:  578:          return set_guards (block, bytes, SOURCE_REALLOC);
call    0 returned 100%
        -:  579:        }
        -:  580:      else
        -:  581:        {
        -:  582:          void *block;
        -:  583:          
    #####:  584:          block = malloc (bytes + GUARD_EXTRA_SIZE);
call    0 never executed
        -:  585:
    #####:  586:          if (block)
branch  0 never executed
branch  1 never executed
    #####:  587:            n_blocks_outstanding += 1;
        -:  588:          
    #####:  589:          return set_guards (block, bytes, SOURCE_REALLOC_NULL);   
call    0 never executed
        -:  590:        }
        -:  591:    }
        -:  592:#endif
        -:  593:  else
        -:  594:    {
        -:  595:      void *mem;
 16087147:  596:      mem = realloc (memory, bytes);
call    0 returned 100%
        -:  597:#ifdef DBUS_BUILD_TESTS
 16087147:  598:      if (memory == NULL && mem != NULL)
branch  0 taken 1% (fallthrough)
branch  1 taken 99%
branch  2 taken 100% (fallthrough)
branch  3 taken 0%
    40524:  599:        n_blocks_outstanding += 1;
        -:  600:#endif
 16087147:  601:      return mem;
        -:  602:    }
        -:  603:}
        -:  604:
        -:  605:/**
        -:  606: * Frees a block of memory previously allocated by dbus_malloc() or
        -:  607: * dbus_malloc0(). If passed #NULL, does nothing.
        -:  608: * 
        -:  609: * @param memory block to be freed
        -:  610: */
        -:  611:void
        -:  612:dbus_free (void  *memory)
function dbus_free called 8781797 returned 100% blocks executed 100%
  8781797:  613:{
        -:  614:#ifdef DBUS_BUILD_TESTS
  8781797:  615:  if (guards)
branch  0 taken 1% (fallthrough)
branch  1 taken 99%
        -:  616:    {
        1:  617:      check_guards (memory, TRUE);
call    0 returned 100%
        1:  618:      if (memory)
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
        -:  619:        {
        1:  620:          n_blocks_outstanding -= 1;
        -:  621:          
        1:  622:          _dbus_assert (n_blocks_outstanding >= 0);
call    0 returned 100%
        -:  623:          
        1:  624:          free (((unsigned char*)memory) - GUARD_START_OFFSET);
call    0 returned 100%
        -:  625:        }
        -:  626:      
        1:  627:      return;
        -:  628:    }
        -:  629:#endif
        -:  630:    
  8781796:  631:  if (memory) /* we guarantee it's safe to free (NULL) */
branch  0 taken 96% (fallthrough)
branch  1 taken 4%
        -:  632:    {
        -:  633:#ifdef DBUS_BUILD_TESTS
  8451736:  634:      n_blocks_outstanding -= 1;
        -:  635:      
  8451736:  636:      _dbus_assert (n_blocks_outstanding >= 0);
call    0 returned 100%
        -:  637:#endif
        -:  638:
  8451736:  639:      free (memory);
call    0 returned 100%
        -:  640:    }
        -:  641:}
        -:  642:
        -:  643:/**
        -:  644: * Frees a #NULL-terminated array of strings.
        -:  645: * If passed #NULL, does nothing.
        -:  646: *
        -:  647: * @param str_array the array to be freed
        -:  648: */
        -:  649:void
        -:  650:dbus_free_string_array (char **str_array)
function dbus_free_string_array called 29526 returned 100% blocks executed 100%
    29526:  651:{
    29526:  652:  if (str_array)
branch  0 taken 38% (fallthrough)
branch  1 taken 62%
        -:  653:    {
        -:  654:      int i;
        -:  655:
    11143:  656:      i = 0;
    38713:  657:      while (str_array[i])
branch  0 taken 60%
branch  1 taken 40% (fallthrough)
        -:  658:	{
    16427:  659:	  dbus_free (str_array[i]);
call    0 returned 100%
    16427:  660:	  i++;
        -:  661:	}
        -:  662:
    11143:  663:      dbus_free (str_array);
call    0 returned 100%
        -:  664:    }
    29526:  665:}
        -:  666:
        -:  667:/** @} */ /* End of public API docs block */
        -:  668:
        -:  669:
        -:  670:/**
        -:  671: * @addtogroup DBusMemoryInternals
        -:  672: *
        -:  673: * @{
        -:  674: */
        -:  675:
        -:  676:/**
        -:  677: * _dbus_current_generation is used to track each
        -:  678: * time that dbus_shutdown() is called, so we can
        -:  679: * reinit things after it's been called. It is simply
        -:  680: * incremented each time we shut down.
        -:  681: */
        -:  682:int _dbus_current_generation = 1;
        -:  683:
        -:  684:/**
        -:  685: * Represents a function to be called on shutdown.
        -:  686: */
        -:  687:typedef struct ShutdownClosure ShutdownClosure;
        -:  688:
        -:  689:/**
        -:  690: * This struct represents a function to be called on shutdown.
        -:  691: */
        -:  692:struct ShutdownClosure
        -:  693:{
        -:  694:  ShutdownClosure *next;     /**< Next ShutdownClosure */
        -:  695:  DBusShutdownFunction func; /**< Function to call */
        -:  696:  void *data;                /**< Data for function */
        -:  697:};
        -:  698:
        -:  699:_DBUS_DEFINE_GLOBAL_LOCK (shutdown_funcs);
        -:  700:static ShutdownClosure *registered_globals = NULL;
        -:  701:
        -:  702:/**
        -:  703: * Register a cleanup function to be called exactly once
        -:  704: * the next time dbus_shutdown() is called.
        -:  705: *
        -:  706: * @param func the function
        -:  707: * @param data data to pass to the function
        -:  708: * @returns #FALSE on not enough memory
        -:  709: */
        -:  710:dbus_bool_t
        -:  711:_dbus_register_shutdown_func (DBusShutdownFunction  func,
        -:  712:                              void                 *data)
function _dbus_register_shutdown_func called 2805 returned 100% blocks executed 86%
     2805:  713:{
        -:  714:  ShutdownClosure *c;
        -:  715:
     2805:  716:  c = dbus_new (ShutdownClosure, 1);
call    0 returned 100%
        -:  717:
     2805:  718:  if (c == NULL)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
    #####:  719:    return FALSE;
        -:  720:
     2805:  721:  c->func = func;
     2805:  722:  c->data = data;
        -:  723:
     2805:  724:  _DBUS_LOCK (shutdown_funcs);
call    0 returned 100%
        -:  725:  
     2805:  726:  c->next = registered_globals;
     2805:  727:  registered_globals = c;
        -:  728:
     2805:  729:  _DBUS_UNLOCK (shutdown_funcs);
call    0 returned 100%
        -:  730:  
     2805:  731:  return TRUE;
        -:  732:}
        -:  733:
        -:  734:/** @} */ /* End of private API docs block */
        -:  735:
        -:  736:
        -:  737:/**
        -:  738: * @addtogroup DBusMemory
        -:  739: *
        -:  740: * @{
        -:  741: */
        -:  742:
        -:  743:/**
        -:  744: * The D-BUS library keeps some internal global variables, for example
        -:  745: * to cache the username of the current process.  This function is
        -:  746: * used to free these global variables.  It is really useful only for
        -:  747: * leak-checking cleanliness and the like. WARNING: this function is
        -:  748: * NOT thread safe, it must be called while NO other threads are using
        -:  749: * D-BUS. You cannot continue using D-BUS after calling this function,
        -:  750: * as it does things like free global mutexes created by
        -:  751: * dbus_threads_init(). To use a D-BUS function after calling
        -:  752: * dbus_shutdown(), you have to start over from scratch, e.g. calling
        -:  753: * dbus_threads_init() again.
        -:  754: */
        -:  755:void
        -:  756:dbus_shutdown (void)
function dbus_shutdown called 34 returned 100% blocks executed 100%
       34:  757:{
       84:  758:  while (registered_globals != NULL)
branch  0 taken 32%
branch  1 taken 68% (fallthrough)
        -:  759:    {
        -:  760:      ShutdownClosure *c;
        -:  761:
       16:  762:      c = registered_globals;
       16:  763:      registered_globals = c->next;
        -:  764:      
       16:  765:      (* c->func) (c->data);
call    0 returned 100%
        -:  766:      
       16:  767:      dbus_free (c);
call    0 returned 100%
        -:  768:    }
        -:  769:
       34:  770:  _dbus_current_generation += 1;
       34:  771:}
        -:  772:
        -:  773:/** @} */ /** End of public API docs block */
        -:  774:
        -:  775:#ifdef DBUS_BUILD_TESTS
        -:  776:#include "dbus-test.h"
        -:  777:
        -:  778:/**
        -:  779: * @ingroup DBusMemoryInternals
        -:  780: * Unit test for DBusMemory
        -:  781: * @returns #TRUE on success.
        -:  782: */
        -:  783:dbus_bool_t
        -:  784:_dbus_memory_test (void)
function _dbus_memory_test called 1 returned 100% blocks executed 82%
        1:  785:{
        -:  786:  dbus_bool_t old_guards;
        -:  787:  void *p;
        -:  788:  size_t size;
        -:  789:
        1:  790:  old_guards = guards;
        1:  791:  guards = TRUE;
        1:  792:  p = dbus_malloc (4);
call    0 returned 100%
        1:  793:  if (p == NULL)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
    #####:  794:    _dbus_assert_not_reached ("no memory");
call    0 never executed
       64:  795:  for (size = 4; size < 256; size += 4)
branch  0 taken 98%
branch  1 taken 2% (fallthrough)
        -:  796:    {
       63:  797:      p = dbus_realloc (p, size);
call    0 returned 100%
       63:  798:      if (p == NULL)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
    #####:  799:	_dbus_assert_not_reached ("no memory");
call    0 never executed
        -:  800:    }
       65:  801:  for (size = 256; size != 0; size -= 4)
branch  0 taken 98%
branch  1 taken 2% (fallthrough)
        -:  802:    {
       64:  803:      p = dbus_realloc (p, size);
call    0 returned 100%
       64:  804:      if (p == NULL)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
    #####:  805:	_dbus_assert_not_reached ("no memory");
call    0 never executed
        -:  806:    }
        1:  807:  dbus_free (p);
call    0 returned 100%
        1:  808:  guards = old_guards;
        1:  809:  return TRUE;
        -:  810:}
        -:  811:
        -:  812:#endif