/** * Allocates the given number of bytes, as with standard malloc(), but * all bytes are initialized to zero as with calloc(). Guaranteed to * return #NULL if bytes is zero on all platforms. Returns #NULL if the * allocation fails. The memory must be released with dbus_free(). * * dbus_malloc0() memory is NOT safe to free with regular free() from * the C library. Free it with dbus_free() only. * * @param bytes number of bytes to allocate * @return allocated memory, or #NULL if the allocation fails. */ void* dbus_malloc0 (size_t bytes) { #ifdef DBUS_BUILD_TESTS _dbus_initialize_malloc_debug (); if (_dbus_decrement_fail_alloc_counter ()) { _dbus_verbose (" FAILING malloc0 of %ld bytes\n", (long) bytes); return NULL; } #endif if (bytes == 0) return NULL; #ifdef DBUS_BUILD_TESTS else if (fail_size != 0 && bytes > fail_size) return NULL; else if (guards) { void *block; block = calloc (bytes + GUARD_EXTRA_SIZE, 1); if (block) { _dbus_atomic_inc (&n_blocks_outstanding); } else if (malloc_cannot_fail) { _dbus_warn ("out of memory: calloc (%ld + %ld, 1)\n", (long) bytes, (long) GUARD_EXTRA_SIZE); _dbus_abort (); } return set_guards (block, bytes, SOURCE_MALLOC_ZERO); } #endif else { void *mem; mem = calloc (bytes, 1); #ifdef DBUS_BUILD_TESTS if (mem) { _dbus_atomic_inc (&n_blocks_outstanding); } else if (malloc_cannot_fail) { _dbus_warn ("out of memory: calloc (%ld)\n", (long) bytes); _dbus_abort (); } #endif return mem; } }
/** * Allocates the given number of bytes, as with standard * malloc(). Guaranteed to return #NULL if bytes is zero * on all platforms. Returns #NULL if the allocation fails. * The memory must be released with dbus_free(). * * dbus_malloc() memory is NOT safe to free with regular free() from * the C library. Free it with dbus_free() only. * * @param bytes number of bytes to allocate * @return allocated memory, or #NULL if the allocation fails. */ void* dbus_malloc (size_t bytes) { #ifdef DBUS_ENABLE_EMBEDDED_TESTS _dbus_initialize_malloc_debug (); if (_dbus_decrement_fail_alloc_counter ()) { _dbus_verbose (" FAILING malloc of %ld bytes\n", (long) bytes); return NULL; } #endif if (bytes == 0) /* some system mallocs handle this, some don't */ return NULL; #ifdef DBUS_ENABLE_EMBEDDED_TESTS else if (fail_size != 0 && bytes > fail_size) return NULL; else if (guards) { void *block; block = malloc (bytes + GUARD_EXTRA_SIZE); if (block) { _dbus_atomic_inc (&n_blocks_outstanding); } else if (malloc_cannot_fail) { _dbus_warn ("out of memory: malloc (%ld + %ld)\n", (long) bytes, (long) GUARD_EXTRA_SIZE); _dbus_abort (); } return set_guards (block, bytes, SOURCE_MALLOC); } #endif else { void *mem; mem = malloc (bytes); #ifdef DBUS_ENABLE_EMBEDDED_TESTS if (mem) { _dbus_atomic_inc (&n_blocks_outstanding); } else if (malloc_cannot_fail) { _dbus_warn ("out of memory: malloc (%ld)\n", (long) bytes); _dbus_abort (); } #endif return mem; } }
/** * Internals of _dbus_assert_not_reached(); it's a function * rather than a macro with the inline code so * that the assertion failure blocks don't show up * in test suite coverage, and to shrink code size. * * @param explanation what was reached that shouldn't have been * @param file file the assertion is in * @param line line the assertion is in */ void _dbus_real_assert_not_reached (const char *explanation, const char *file, int line) { _dbus_warn ("File \"%s\" line %d process %lu should not have been reached: %s\n", file, line, _dbus_pid_for_log (), explanation); _dbus_abort (); }
/** * Internals of _dbus_assert(); it's a function * rather than a macro with the inline code so * that the assertion failure blocks don't show up * in test suite coverage, and to shrink code size. * * @param condition TRUE if assertion succeeded * @param condition_text condition as a string * @param file file the assertion is in * @param line line the assertion is in * @param func function the assertion is in */ void _dbus_real_assert (dbus_bool_t condition, const char *condition_text, const char *file, int line, const char *func) { if (_DBUS_UNLIKELY (!condition)) { _dbus_warn ("%lu: assertion failed \"%s\" file \"%s\" line %d function %s\n", _dbus_pid_for_log (), condition_text, file, line, func); _dbus_abort (); } }
/** * Prints a warning message to stderr. Can optionally be made to exit * fatally by setting DBUS_FATAL_WARNINGS, but this is rarely * used. This function should be considered pretty much equivalent to * fprintf(stderr). _dbus_warn_check_failed() on the other hand is * suitable for use when a programming mistake has been made. * * @param format printf-style format string. */ void _dbus_warn (const char *format, ...) { va_list args; if (!warn_initted) init_warnings (); va_start (args, format); vfprintf (stderr, format, args); va_end (args); if (fatal_warnings) { fflush (stderr); _dbus_abort (); } }
/** * Prints a "critical" warning to stderr when an assertion fails; * differs from _dbus_warn primarily in that it prefixes the pid and * defaults to fatal. This should be used only when a programming * error has been detected. (NOT for unavoidable errors that an app * might handle - those should be returned as DBusError.) Calling this * means "there is a bug" */ void _dbus_warn_check_failed(const char *format, ...) { va_list args; if (!warn_initted) init_warnings (); fprintf (stderr, "process %lu: ", _dbus_pid_for_log ()); va_start (args, format); vfprintf (stderr, format, args); va_end (args); if (fatal_warnings_on_check_failed) { fflush (stderr); _dbus_abort (); } }
/** * Resizes a block of memory previously allocated by dbus_malloc() or * dbus_malloc0(). Guaranteed to free the memory and return #NULL if bytes * is zero on all platforms. Returns #NULL if the resize fails. * If the resize fails, the memory is not freed. * * @param memory block to be resized * @param bytes new size of the memory block * @return allocated memory, or #NULL if the resize fails. */ void* dbus_realloc (void *memory, size_t bytes) { #ifdef DBUS_BUILD_TESTS _dbus_initialize_malloc_debug (); if (_dbus_decrement_fail_alloc_counter ()) { _dbus_verbose (" FAILING realloc of %ld bytes\n", (long) bytes); return NULL; } #endif if (bytes == 0) /* guarantee this is safe */ { dbus_free (memory); return NULL; } #ifdef DBUS_BUILD_TESTS else if (fail_size != 0 && bytes > fail_size) return NULL; else if (guards) { if (memory) { size_t old_bytes; void *block; check_guards (memory, FALSE); block = realloc (((unsigned char*)memory) - GUARD_START_OFFSET, bytes + GUARD_EXTRA_SIZE); if (block == NULL) { if (malloc_cannot_fail) { _dbus_warn ("out of memory: realloc (%p, %ld + %ld)\n", memory, (long) bytes, (long) GUARD_EXTRA_SIZE); _dbus_abort (); } return NULL; } old_bytes = *(dbus_uint32_t*)block; if (bytes >= old_bytes) /* old guards shouldn't have moved */ check_guards (((unsigned char*)block) + GUARD_START_OFFSET, FALSE); return set_guards (block, bytes, SOURCE_REALLOC); } else { void *block; block = malloc (bytes + GUARD_EXTRA_SIZE); if (block) { _dbus_atomic_inc (&n_blocks_outstanding); } else if (malloc_cannot_fail) { _dbus_warn ("out of memory: malloc (%ld + %ld)\n", (long) bytes, (long) GUARD_EXTRA_SIZE); _dbus_abort (); } return set_guards (block, bytes, SOURCE_REALLOC_NULL); } } #endif else { void *mem; mem = realloc (memory, bytes); #ifdef DBUS_BUILD_TESTS if (mem == NULL && malloc_cannot_fail) { _dbus_warn ("out of memory: malloc (%ld)\n", (long) bytes); _dbus_abort (); } if (memory == NULL && mem != NULL) _dbus_atomic_inc (&n_blocks_outstanding); #endif return mem; } }