Commit f05f87a8 authored by Havoc Pennington's avatar Havoc Pennington

2003-03-15 Havoc Pennington <hp@pobox.com>

	* bus/dispatch.c (bus_dispatch_test): OK, now finally actually
	write useful test code, after all that futzing around ;-)

	Test does not yet pass because we can't handle OOM in
	_dbus_transport_messages_pending (basically,
	dbus_connection_preallocate_send() does not prealloc the write
	watch). To fix this, I think we need to add new stuff to
	set_watch_functions, namely a SetEnabled function so we can alloc
	the watch earlier, then enable it later.

	* dbus/Makefile.am (libdbus_convenience_la_SOURCES): move
	dbus-memory.c to the convenience lib

	* bus/test.c: rename some static functions to keep them clearly
	distinct from stuff in connection.c. Handle client disconnection.
parent 169238e9
2003-03-15 Havoc Pennington <hp@pobox.com>
* bus/dispatch.c (bus_dispatch_test): OK, now finally actually
write useful test code, after all that futzing around ;-)
Test does not yet pass because we can't handle OOM in
_dbus_transport_messages_pending (basically,
dbus_connection_preallocate_send() does not prealloc the write
watch). To fix this, I think we need to add new stuff to
set_watch_functions, namely a SetEnabled function so we can alloc
the watch earlier, then enable it later.
* dbus/Makefile.am (libdbus_convenience_la_SOURCES): move
dbus-memory.c to the convenience lib
* bus/test.c: rename some static functions to keep them clearly
distinct from stuff in connection.c. Handle client disconnection.
2003-03-14 Havoc Pennington <hp@pobox.com>
* bus/dispatch.c (bus_dispatch_test): do test using debug-pipe
......
......@@ -56,8 +56,6 @@ bus_connection_disconnected (DBusConnection *connection)
{
BusConnectionData *d;
BusService *service;
_dbus_warn ("Disconnected\n");
d = BUS_CONNECTION_DATA (connection);
_dbus_assert (d != NULL);
......
......@@ -377,6 +377,10 @@ bus_dispatch_remove_connection (DBusConnection *connection)
#ifdef DBUS_BUILD_TESTS
typedef dbus_bool_t (* Check1Func) (BusContext *context);
typedef dbus_bool_t (* Check2Func) (BusContext *context,
DBusConnection *connection);
static void
flush_bus (BusContext *context)
{
......@@ -384,6 +388,15 @@ flush_bus (BusContext *context)
;
}
static void
kill_client_connection (DBusConnection *connection)
{
/* kick in the disconnect handler that unrefs the connection */
dbus_connection_disconnect (connection);
while (dbus_connection_dispatch_message (connection))
;
}
/* returns TRUE if the correct thing happens,
* but the correct thing may include OOM errors.
*/
......@@ -393,6 +406,10 @@ check_hello_message (BusContext *context,
{
DBusMessage *message;
dbus_int32_t serial;
dbus_bool_t retval;
DBusError error;
dbus_error_init (&error);
message = dbus_message_new (DBUS_SERVICE_DBUS,
DBUS_MESSAGE_HELLO);
......@@ -404,25 +421,150 @@ check_hello_message (BusContext *context,
return TRUE;
dbus_message_unref (message);
message = NULL;
flush_bus (context);
if (!dbus_connection_get_is_connected (connection))
{
_dbus_verbose ("connection was disconnected\n");
return TRUE;
}
retval = FALSE;
message = dbus_connection_pop_message (connection);
if (message == NULL)
{
_dbus_warn ("Did not receive a reply to %s %d on %p\n",
DBUS_MESSAGE_HELLO, serial, connection);
return FALSE;
goto out;
}
_dbus_verbose ("Received %s on %p\n",
dbus_message_get_name (message), connection);
if (dbus_message_get_is_error (message))
{
if (dbus_message_name_is (message,
DBUS_ERROR_NO_MEMORY))
{
; /* good, this is a valid response */
}
else
{
_dbus_warn ("Did not expect error %s\n",
dbus_message_get_name (message));
goto out;
}
}
else
{
char *str;
if (dbus_message_name_is (message,
DBUS_MESSAGE_HELLO))
{
; /* good, expected */
}
else
{
_dbus_warn ("Did not expect reply %s\n",
dbus_message_get_name (message));
goto out;
}
if (!dbus_message_get_args (message, &error,
DBUS_TYPE_STRING, &str,
DBUS_TYPE_INVALID))
{
_dbus_warn ("Did not get the expected single string argument\n");
goto out;
}
_dbus_verbose ("Got hello name: %s\n", str);
dbus_free (str);
}
retval = TRUE;
dbus_message_unref (message);
out:
if (message)
dbus_message_unref (message);
return retval;
}
/* returns TRUE if the correct thing happens,
* but the correct thing may include OOM errors.
*/
static dbus_bool_t
check_hello_connection (BusContext *context)
{
DBusConnection *connection;
DBusResultCode result;
result = DBUS_RESULT_SUCCESS;
connection = dbus_connection_open ("debug-pipe:name=test-server", &result);
if (connection == NULL)
{
_dbus_assert (result != DBUS_RESULT_SUCCESS);
return TRUE;
}
if (!bus_setup_debug_client (connection))
{
dbus_connection_unref (connection);
return TRUE;
}
if (!check_hello_message (context, connection))
return FALSE;
kill_client_connection (connection);
return TRUE;
}
static void
check1_try_iterations (BusContext *context,
const char *description,
Check1Func func)
{
int approx_mallocs;
/* Run once to see about how many mallocs are involved */
_dbus_set_fail_alloc_counter (_DBUS_INT_MAX);
if (! (*func) (context))
_dbus_assert_not_reached ("test failed");
approx_mallocs = _DBUS_INT_MAX - _dbus_get_fail_alloc_counter ();
_dbus_verbose ("=================\n%s: about %d mallocs total\n=================\n",
description, approx_mallocs);
approx_mallocs += 10; /* fudge factor */
/* Now run failing each malloc */
while (approx_mallocs >= 0)
{
_dbus_set_fail_alloc_counter (approx_mallocs);
_dbus_verbose ("\n===\n %s: (will fail malloc %d)\n===\n",
description, approx_mallocs);
if (! (*func) (context))
_dbus_assert_not_reached ("test failed");
approx_mallocs -= 1;
}
_dbus_set_fail_alloc_counter (_DBUS_INT_MAX);
}
dbus_bool_t
bus_dispatch_test (const DBusString *test_data_dir)
{
......@@ -440,6 +582,9 @@ bus_dispatch_test (const DBusString *test_data_dir)
&error);
if (context == NULL)
_dbus_assert_not_reached ("could not alloc context");
check1_try_iterations (context, "create_and_hello",
check_hello_connection);
foo = dbus_connection_open ("debug-pipe:name=test-server", &result);
if (foo == NULL)
......@@ -464,6 +609,10 @@ bus_dispatch_test (const DBusString *test_data_dir)
_dbus_assert_not_reached ("hello message failed");
if (!check_hello_message (context, baz))
_dbus_assert_not_reached ("hello message failed");
dbus_connection_unref (foo);
dbus_connection_unref (bar);
dbus_connection_unref (baz);
return TRUE;
}
......
......@@ -26,6 +26,7 @@
#ifdef DBUS_BUILD_TESTS
#include "test.h"
#include "loop.h"
#include <dbus/dbus-internals.h>
/* The "debug client" watch/timeout handlers don't dispatch messages,
* as we manually pull them in order to verify them. This is why they
......@@ -33,7 +34,7 @@
*/
static void
connection_watch_callback (DBusWatch *watch,
client_watch_callback (DBusWatch *watch,
unsigned int condition,
void *data)
{
......@@ -47,22 +48,22 @@ connection_watch_callback (DBusWatch *watch,
}
static dbus_bool_t
add_connection_watch (DBusWatch *watch,
add_client_watch (DBusWatch *watch,
DBusConnection *connection)
{
return bus_loop_add_watch (watch, connection_watch_callback, connection,
return bus_loop_add_watch (watch, client_watch_callback, connection,
NULL);
}
static void
remove_connection_watch (DBusWatch *watch,
remove_client_watch (DBusWatch *watch,
DBusConnection *connection)
{
bus_loop_remove_watch (watch, connection_watch_callback, connection);
bus_loop_remove_watch (watch, client_watch_callback, connection);
}
static void
connection_timeout_callback (DBusTimeout *timeout,
client_timeout_callback (DBusTimeout *timeout,
void *data)
{
DBusConnection *connection = data;
......@@ -75,43 +76,85 @@ connection_timeout_callback (DBusTimeout *timeout,
}
static dbus_bool_t
add_connection_timeout (DBusTimeout *timeout,
add_client_timeout (DBusTimeout *timeout,
DBusConnection *connection)
{
return bus_loop_add_timeout (timeout, connection_timeout_callback, connection, NULL);
return bus_loop_add_timeout (timeout, client_timeout_callback, connection, NULL);
}
static void
remove_connection_timeout (DBusTimeout *timeout,
remove_client_timeout (DBusTimeout *timeout,
DBusConnection *connection)
{
bus_loop_remove_timeout (timeout, connection_timeout_callback, connection);
bus_loop_remove_timeout (timeout, client_timeout_callback, connection);
}
static DBusHandlerResult
client_disconnect_handler (DBusMessageHandler *handler,
DBusConnection *connection,
DBusMessage *message,
void *user_data)
{
dbus_connection_unref (connection);
return DBUS_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
}
dbus_bool_t
bus_setup_debug_client (DBusConnection *connection)
{
DBusMessageHandler *disconnect_handler;
const char *to_handle[] = { DBUS_MESSAGE_LOCAL_DISCONNECT };
dbus_bool_t retval;
if (!dbus_connection_set_watch_functions (connection,
(DBusAddWatchFunction) add_connection_watch,
(DBusRemoveWatchFunction) remove_connection_watch,
connection,
NULL))
disconnect_handler = dbus_message_handler_new (client_disconnect_handler,
NULL, NULL);
if (disconnect_handler == NULL)
return FALSE;
if (!dbus_connection_register_handler (connection,
disconnect_handler,
to_handle,
_DBUS_N_ELEMENTS (to_handle)))
{
dbus_connection_disconnect (connection);
dbus_message_handler_unref (disconnect_handler);
return FALSE;
}
retval = FALSE;
if (!dbus_connection_set_watch_functions (connection,
(DBusAddWatchFunction) add_client_watch,
(DBusRemoveWatchFunction) remove_client_watch,
connection,
NULL))
goto out;
if (!dbus_connection_set_timeout_functions (connection,
(DBusAddTimeoutFunction) add_connection_timeout,
(DBusRemoveTimeoutFunction) remove_connection_timeout,
(DBusAddTimeoutFunction) add_client_timeout,
(DBusRemoveTimeoutFunction) remove_client_timeout,
connection, NULL))
goto out;
retval = TRUE;
out:
if (!retval)
{
dbus_connection_disconnect (connection);
return FALSE;
dbus_connection_unregister_handler (connection,
disconnect_handler,
to_handle,
_DBUS_N_ELEMENTS (to_handle));
dbus_connection_set_watch_functions (connection,
NULL, NULL, NULL, NULL);
dbus_connection_set_timeout_functions (connection,
NULL, NULL, NULL, NULL);
}
return TRUE;
dbus_message_handler_unref (disconnect_handler);
return retval;
}
#endif
......@@ -22,6 +22,7 @@
*
*/
#include <config.h>
#include "utils.h"
#include <dbus/dbus-sysdeps.h>
......@@ -30,6 +31,11 @@ const char bus_no_memory_message[] = "Memory allocation failure in message bus";
void
bus_wait_for_memory (void)
{
#ifdef DBUS_BUILD_TESTS
/* make tests go fast */
_dbus_sleep_milliseconds (10);
#else
_dbus_sleep_milliseconds (500);
#endif
}
......@@ -136,6 +136,8 @@ AC_CHECK_LIB(nsl,gethostbyname)
AC_CHECK_FUNCS(vsnprintf vasprintf nanosleep usleep poll setenv socketpair)
AC_CHECK_HEADERS(execinfo.h, [AC_CHECK_FUNCS(backtrace)])
AC_CACHE_CHECK([for posix getpwnam_r],
ac_cv_func_posix_getpwnam_r,
[AC_TRY_RUN([
......
......@@ -34,7 +34,6 @@ libdbus_1_la_SOURCES= \
dbus-errors.c \
dbus-keyring.c \
dbus-keyring.h \
dbus-memory.c \
dbus-message.c \
dbus-message-handler.c \
dbus-message-internal.h \
......@@ -88,6 +87,7 @@ libdbus_convenience_la_SOURCES= \
dbus-list.h \
dbus-marshal.c \
dbus-marshal.h \
dbus-memory.c \
dbus-mempool.c \
dbus-mempool.h \
dbus-message-builder.c \
......
......@@ -256,6 +256,8 @@ dbus_malloc (size_t bytes)
{
if (fail_counts != -1)
_dbus_set_fail_alloc_counter (fail_counts);
_dbus_verbose (" FAILING malloc of %d bytes\n", bytes);
return NULL;
}
......@@ -297,6 +299,8 @@ dbus_malloc0 (size_t bytes)
{
if (fail_counts != -1)
_dbus_set_fail_alloc_counter (fail_counts);
_dbus_verbose (" FAILING malloc0 of %d bytes\n", bytes);
return NULL;
}
......@@ -340,6 +344,8 @@ dbus_realloc (void *memory,
{
if (fail_counts != -1)
_dbus_set_fail_alloc_counter (fail_counts);
_dbus_verbose (" FAILING realloc of %d bytes\n", bytes);
return NULL;
}
......
......@@ -203,7 +203,10 @@ void*
_dbus_mem_pool_alloc (DBusMemPool *pool)
{
if (_dbus_decrement_fail_alloc_counter ())
return NULL;
{
_dbus_verbose (" FAILING mempool alloc\n");
return NULL;
}
if (pool->free_elements)
{
......
......@@ -628,8 +628,10 @@ _dbus_message_add_size_counter (DBusMessage *message,
_dbus_string_get_length (&message->header) +
_dbus_string_get_length (&message->body);
#if 0
_dbus_verbose ("message has size %ld\n",
message->size_counter_delta);
#endif
_dbus_counter_adjust (message->size_counter, message->size_counter_delta);
}
......@@ -2587,13 +2589,15 @@ decode_header_data (const DBusString *data,
}
fields[FIELD_SERVICE].offset = _DBUS_ALIGN_VALUE (pos + 1, 4);
#if 0
_dbus_verbose ("Found service name at offset %d\n",
fields[FIELD_SERVICE].offset);
#endif
break;
case DBUS_HEADER_FIELD_NAME_AS_UINT32:
if (fields[FIELD_NAME].offset >= 0)
{
{
_dbus_verbose ("%s field provided twice\n",
DBUS_HEADER_FIELD_NAME);
return FALSE;
......@@ -2601,8 +2605,10 @@ decode_header_data (const DBusString *data,
fields[FIELD_NAME].offset = _DBUS_ALIGN_VALUE (pos + 1, 4);
#if 0
_dbus_verbose ("Found message name at offset %d\n",
fields[FIELD_NAME].offset);
#endif
break;
case DBUS_HEADER_FIELD_SENDER_AS_UINT32:
if (fields[FIELD_SENDER].offset >= 0)
......
......@@ -50,6 +50,10 @@
#ifdef HAVE_POLL
#include <sys/poll.h>
#endif
#ifdef HAVE_BACKTRACE
#include <execinfo.h>
#endif
#ifndef O_BINARY
#define O_BINARY 0
......@@ -2827,5 +2831,35 @@ _dbus_close (int fd,
return TRUE;
}
/**
* On GNU libc systems, print a crude backtrace to the verbose log.
* On other systems, print "no backtrace support"
*
*/
void
_dbus_print_backtrace (void)
{
#if defined (HAVE_BACKTRACE) && defined (DBUS_ENABLE_VERBOSE_MODE)
void *bt[500];
int bt_size;
int i;
char **syms;
bt_size = backtrace (bt, 500);
syms = backtrace_symbols (bt, bt_size);
i = 0;
while (i < bt_size)
{
_dbus_verbose (" %s\n", syms[i]);
++i;
}
free (syms);
#else
_dbus_verbose (" D-BUS not compiled with backtrace support\n");
#endif
}
/** @} end of sysdeps */
......@@ -205,6 +205,8 @@ dbus_bool_t _dbus_full_duplex_pipe (int *fd1,
dbus_bool_t _dbus_close (int fd,
DBusError *error);
void _dbus_print_backtrace (void);
DBUS_END_DECLS;
#endif /* DBUS_SYSDEPS_H */
......@@ -164,8 +164,10 @@ check_write_watch (DBusTransport *transport)
}
else
{
#if 0
_dbus_verbose ("Write watch is unchanged from %p on fd %d\n",
unix_transport->write_watch, unix_transport->fd);
#endif
}
out:
......@@ -190,8 +192,10 @@ check_read_watch (DBusTransport *transport)
need_read_watch = transport->receive_credentials_pending ||
_dbus_auth_do_work (transport->auth) == DBUS_AUTH_STATE_WAITING_FOR_INPUT;
#if 0
_dbus_verbose ("need_read_watch = %d authenticated = %d\n",
need_read_watch, _dbus_transport_get_is_authenticated (transport));
#endif
if (transport->disconnected)
need_read_watch = FALSE;
......@@ -232,8 +236,10 @@ check_read_watch (DBusTransport *transport)
}
else
{
#if 0
_dbus_verbose ("Read watch is unchanged from %p on fd %d\n",
unix_transport->read_watch, unix_transport->fd);
#endif
}
out:
......@@ -621,7 +627,9 @@ do_writing (DBusTransport *transport)
_dbus_assert (message != NULL);
_dbus_message_lock (message);
#if 0
_dbus_verbose ("writing message %p\n", message);
#endif
_dbus_message_get_network_data (message,
&header, &body);
......@@ -647,8 +655,10 @@ do_writing (DBusTransport *transport)
total_bytes_to_write = _dbus_string_get_length (&unix_transport->encoded_message);
#if 0
_dbus_verbose ("encoded message is %d bytes\n",
total_bytes_to_write);
#endif
bytes_written =
_dbus_write (unix_transport->fd,
......@@ -660,8 +670,10 @@ do_writing (DBusTransport *transport)
{
total_bytes_to_write = header_len + body_len;
#if 0
_dbus_verbose ("message is %d bytes\n",
total_bytes_to_write);
#endif
if (unix_transport->message_bytes_written < header_len)
{
......@@ -868,14 +880,18 @@ unix_handle_watch (DBusTransport *transport,
if (watch == unix_transport->read_watch &&
(flags & DBUS_WATCH_READABLE))
{
#if 0
_dbus_verbose ("handling read watch\n");
#endif
do_authentication (transport, TRUE, FALSE);
do_reading (transport);
}
else if (watch == unix_transport->write_watch &&
(flags & DBUS_WATCH_WRITABLE))
{
#if 0
_dbus_verbose ("handling write watch\n");
#endif
do_authentication (transport, FALSE, TRUE);
do_writing (transport);
}
......
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