Commit 07a795f1 authored by Havoc Pennington's avatar Havoc Pennington

2003-02-14 Havoc Pennington <hp@pobox.com>

	* dbus/dbus-mempool.c: fail if the debug functions so indicate

	* dbus/dbus-memory.c: fail if the debug functions indicate we
	should

	* dbus/dbus-internals.c (_dbus_set_fail_alloc_counter)
	(_dbus_decrement_fail_alloc_counter): debug functions to
	simulate memory allocation failures
parent b544e593
2003-02-14 Havoc Pennington <hp@pobox.com>
* dbus/dbus-mempool.c: fail if the debug functions so indicate
* dbus/dbus-memory.c: fail if the debug functions indicate we
should
* dbus/dbus-internals.c (_dbus_set_fail_alloc_counter)
(_dbus_decrement_fail_alloc_counter): debug functions to
simulate memory allocation failures
2003-02-14 Havoc Pennington <hp@pobox.com>
* dbus/dbus-errors.h (struct DBusError): add a word of padding
......
......@@ -391,4 +391,56 @@ _dbus_type_to_string (int type)
}
}
#ifdef DBUS_BUILD_TESTS
static int fail_alloc_counter = _DBUS_INT_MAX;
/**
* Sets the number of allocations until we simulate a failed
* allocation. If set to 0, the next allocation to run
* fails; if set to 1, one succeeds then the next fails; etc.
* Set to _DBUS_INT_MAX to not fail anything.
*
* @param until_next_fail number of successful allocs before one fails
*/
void
_dbus_set_fail_alloc_counter (int until_next_fail)
{
fail_alloc_counter = until_next_fail;
}
/**
* Gets the number of successful allocs until we'll simulate
* a failed alloc.
*
* @returns current counter value
*/
int
_dbus_get_fail_alloc_counter (void)
{
return fail_alloc_counter;
}
/**
* Called when about to alloc some memory; if
* it returns #TRUE, then the allocation should
* fail. If it returns #FALSE, then the allocation
* should not fail.
*
* @returns #TRUE if this alloc should fail
*/
dbus_bool_t
_dbus_decrement_fail_alloc_counter (void)
{
if (fail_alloc_counter <= 0)
{
fail_alloc_counter = _DBUS_INT_MAX;
return TRUE;
}
else
{
fail_alloc_counter -= 1;
return FALSE;
}
}
#endif /* DBUS_BUILD_TESTS */
/** @} */
......@@ -142,6 +142,17 @@ void _dbus_verbose_bytes_of_string (const DBusString *str,
const char* _dbus_type_to_string (int type);
#ifdef DBUS_BUILD_TESTS
/* Memory debugging */
void _dbus_set_fail_alloc_counter (int until_next_fail);
int _dbus_get_fail_alloc_counter (void);
dbus_bool_t _dbus_decrement_fail_alloc_counter (void);
#else
#define _dbus_set_fail_alloc_counter(n)
#define _dbus_get_fail_alloc_counter _DBUS_INT_MAX
#define _dbus_decrement_fail_alloc_counter FALSE
#endif /* !DBUS_BUILD_TESTS */
DBUS_END_DECLS;
#endif /* DBUS_INTERNALS_H */
/* -*- mode: C; c-file-style: "gnu" -*- */
/* dbus-memory.c D-BUS memory handling
*
* Copyright (C) 2002 Red Hat Inc.
* Copyright (C) 2002, 2003 Red Hat Inc.
*
* Licensed under the Academic Free License version 1.2
*
......@@ -22,6 +22,7 @@
*/
#include "dbus-memory.h"
#include "dbus-internals.h"
#include <stdlib.h>
/**
......@@ -82,6 +83,9 @@
void*
dbus_malloc (size_t bytes)
{
if (_dbus_decrement_fail_alloc_counter ())
return NULL;
if (bytes == 0) /* some system mallocs handle this, some don't */
return NULL;
else
......@@ -100,6 +104,9 @@ dbus_malloc (size_t bytes)
void*
dbus_malloc0 (size_t bytes)
{
if (_dbus_decrement_fail_alloc_counter ())
return NULL;
if (bytes == 0)
return NULL;
else
......@@ -120,6 +127,9 @@ void*
dbus_realloc (void *memory,
size_t bytes)
{
if (_dbus_decrement_fail_alloc_counter ())
return NULL;
if (bytes == 0) /* guarantee this is safe */
{
dbus_free (memory);
......
/* -*- mode: C; c-file-style: "gnu" -*- */
/* dbus-mempool.h Memory pools
*
* Copyright (C) 2002 Red Hat, Inc.
* Copyright (C) 2002, 2003 Red Hat, Inc.
*
* Licensed under the Academic Free License version 1.2
*
......@@ -195,6 +195,9 @@ _dbus_mem_pool_free (DBusMemPool *pool)
void*
_dbus_mem_pool_alloc (DBusMemPool *pool)
{
if (_dbus_decrement_fail_alloc_counter ())
return NULL;
if (pool->free_elements)
{
DBusFreedElement *element = pool->free_elements;
......@@ -216,7 +219,10 @@ _dbus_mem_pool_alloc (DBusMemPool *pool)
/* Need a new block */
DBusMemBlock *block;
int alloc_size;
#ifdef DBUS_BUILD_TESTS
int saved_counter;
#endif
if (pool->block_size <= _DBUS_INT_MAX / 4) /* avoid overflow */
{
/* use a larger block size for our next block */
......@@ -226,12 +232,27 @@ _dbus_mem_pool_alloc (DBusMemPool *pool)
}
alloc_size = sizeof (DBusMemBlock) - ELEMENT_PADDING + pool->block_size;
#ifdef DBUS_BUILD_TESTS
/* We save/restore the counter, so that memory pools won't
* cause a given function to have different number of
* allocations on different invocations. i.e. when testing
* we want consistent alloc patterns. So we skip our
* malloc here for purposes of failed alloc simulation.
*/
saved_counter = _dbus_get_fail_alloc_counter ();
_dbus_set_fail_alloc_counter (_DBUS_INT_MAX);
#endif
if (pool->zero_elements)
block = dbus_malloc0 (alloc_size);
else
block = dbus_malloc (alloc_size);
#ifdef DBUS_BUILD_TESTS
_dbus_set_fail_alloc_counter (saved_counter);
#endif
if (block == NULL)
return NULL;
......
......@@ -2006,6 +2006,12 @@ decode_header_data (const DBusString *data,
* in. This function must always be called, even if no bytes were
* successfully read.
*
* @todo if we run out of memory in here, we offer no way for calling
* code to handle it, i.e. they can't re-run the message parsing
* attempt. Perhaps much of this code could be moved to pop_message()?
* But then that may need to distinguish NULL return for no messages
* from NULL return for errors.
*
* @param loader the loader.
* @param buffer the buffer.
* @param bytes_read number of bytes that were read into the buffer.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment