* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
+
+#include <config.h>
#include "dbus-internals.h"
#include "dbus-protocol.h"
#include "dbus-marshal-basic.h"
#include "dbus-test.h"
+#include "dbus-valgrind-internal.h"
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#ifdef DBUS_USE_OUTPUT_DEBUG_STRING
#include <windows.h>
+#include <mbstring.h>
#endif
/**
*/
/**
- * @def _DBUS_DEFINE_GLOBAL_LOCK
- *
- * Defines a global lock variable with the given name.
- * The lock must be added to the list to initialize
- * in dbus_threads_init().
- */
-
-/**
- * @def _DBUS_DECLARE_GLOBAL_LOCK
- *
- * Expands to declaration of a global lock defined
- * with _DBUS_DEFINE_GLOBAL_LOCK.
- * The lock must be added to the list to initialize
- * in dbus_threads_init().
- */
-
-/**
* @def _DBUS_LOCK
*
- * Locks a global lock
+ * Locks a global lock, initializing it first if necessary.
+ *
+ * @returns #FALSE if not enough memory
*/
/**
#include <pthread.h>
#endif
-#ifdef _MSC_VER
-#define inline
-#endif
#ifdef DBUS_USE_OUTPUT_DEBUG_STRING
static char module_name[1024];
#endif
static char *_dbus_file_path_extract_elements_from_tail(const char *file,int level)
{
static int prefix = -1;
- char *p;
if (prefix == -1)
{
* @param format printf-style format string.
*/
void
+_dbus_verbose_real (
#ifdef DBUS_CPP_SUPPORTS_VARIABLE_MACRO_ARGUMENTS
-_dbus_verbose_real (const char *file,
+ const char *file,
const int line,
const char *function,
- const char *format,
-#else
-_dbus_verbose_real (const char *format,
#endif
+ const char *format,
...)
{
va_list args;
char buf[1024];
strcpy(buf,module_name);
#ifdef DBUS_CPP_SUPPORTS_VARIABLE_MACRO_ARGUMENTS
- vsprintf (buf+strlen(buf), "[%s(%d):%s] ",_dbus_file_path_extract_elements_from_tail(file,2),line,function);
+ sprintf (buf+strlen(buf), "[%s(%d):%s] ",_dbus_file_path_extract_elements_from_tail(file,2),line,function);
#endif
vsprintf (buf+strlen(buf),format, args);
va_end (args);
- OutputDebugString(buf);
+ OutputDebugStringA(buf);
}
#else
#ifdef DBUS_CPP_SUPPORTS_VARIABLE_MACRO_ARGUMENTS
verbose_initted = FALSE;
}
+void
+_dbus_trace_ref (const char *obj_name,
+ void *obj,
+ int old_refcount,
+ int new_refcount,
+ const char *why,
+ const char *env_var,
+ int *enabled)
+{
+ _dbus_assert (obj_name != NULL);
+ _dbus_assert (obj != NULL);
+ _dbus_assert (old_refcount >= -1);
+ _dbus_assert (new_refcount >= -1);
+
+ if (old_refcount == -1)
+ {
+ _dbus_assert (new_refcount == -1);
+ }
+ else
+ {
+ _dbus_assert (new_refcount >= 0);
+ _dbus_assert (old_refcount >= 0);
+ _dbus_assert (old_refcount > 0 || new_refcount > 0);
+ }
+
+ _dbus_assert (why != NULL);
+ _dbus_assert (env_var != NULL);
+ _dbus_assert (enabled != NULL);
+
+ if (*enabled < 0)
+ {
+ const char *s = _dbus_getenv (env_var);
+
+ *enabled = FALSE;
+
+ if (s && *s)
+ {
+ if (*s == '0')
+ *enabled = FALSE;
+ else if (*s == '1')
+ *enabled = TRUE;
+ else
+ _dbus_warn ("%s should be 0 or 1 if set, not '%s'", env_var, s);
+ }
+ }
+
+ if (*enabled)
+ {
+ if (old_refcount == -1)
+ {
+ VALGRIND_PRINTF_BACKTRACE ("%s %p ref stolen (%s)",
+ obj_name, obj, why);
+ _dbus_verbose ("%s %p ref stolen (%s)",
+ obj_name, obj, why);
+ }
+ else
+ {
+ VALGRIND_PRINTF_BACKTRACE ("%s %p %d -> %d refs (%s)",
+ obj_name, obj,
+ old_refcount, new_refcount, why);
+ _dbus_verbose ("%s %p %d -> %d refs (%s)",
+ obj_name, obj, old_refcount, new_refcount, why);
+ }
+ }
+}
+
#endif /* DBUS_ENABLE_VERBOSE_MODE */
/**
{
long now;
- _dbus_get_current_time (&now, NULL);
+ /* don't use monotonic time because the UUID may be saved to disk, e.g.
+ * it may persist across reboots
+ */
+ _dbus_get_real_time (&now, NULL);
uuid->as_uint32s[DBUS_UUID_LENGTH_WORDS - 1] = DBUS_UINT32_TO_BE (now);
goto error;
}
- /* FIXME this is racy; we need a save_file_exclusively
- * function. But in practice this should be fine for now.
- *
- * - first be sure we can create the file and it
- * doesn't exist by creating it empty with O_EXCL
- * - then create it by creating a temporary file and
- * overwriting atomically with rename()
- */
- if (!_dbus_create_file_exclusively (filename, error))
- goto error;
-
if (!_dbus_string_append_byte (&encoded, '\n'))
{
_DBUS_SET_OOM (error);
goto error;
}
- if (!_dbus_string_save_to_file (&encoded, filename, error))
- goto error;
-
- if (!_dbus_make_file_world_readable (filename, error))
+ if (!_dbus_string_save_to_file (&encoded, filename, TRUE, error))
goto error;
_dbus_string_free (&encoded);
}
}
-_DBUS_DEFINE_GLOBAL_LOCK (machine_uuid);
+/* Protected by _DBUS_LOCK (machine_uuid) */
static int machine_uuid_initialized_generation = 0;
static DBusGUID machine_uuid;
{
dbus_bool_t ok;
- _DBUS_LOCK (machine_uuid);
+ if (!_DBUS_LOCK (machine_uuid))
+ return FALSE;
+
if (machine_uuid_initialized_generation != _dbus_current_generation)
{
DBusError error = DBUS_ERROR_INIT;
if (!_dbus_read_local_machine_uuid (&machine_uuid, FALSE,
&error))
{
-#ifndef DBUS_BUILD_TESTS
+#ifndef DBUS_ENABLE_EMBEDDED_TESTS
/* For the test suite, we may not be installed so just continue silently
* here. But in a production build, we want to be nice and loud about
* this.
return ok;
}
-#ifdef DBUS_BUILD_TESTS
-/**
- * Returns a string describing the given name.
- *
- * @param header_field the field to describe
- * @returns a constant string describing the field
- */
-const char *
-_dbus_header_field_to_string (int header_field)
-{
- switch (header_field)
- {
- case DBUS_HEADER_FIELD_INVALID:
- return "invalid";
- case DBUS_HEADER_FIELD_PATH:
- return "path";
- case DBUS_HEADER_FIELD_INTERFACE:
- return "interface";
- case DBUS_HEADER_FIELD_MEMBER:
- return "member";
- case DBUS_HEADER_FIELD_ERROR_NAME:
- return "error-name";
- case DBUS_HEADER_FIELD_REPLY_SERIAL:
- return "reply-serial";
- case DBUS_HEADER_FIELD_DESTINATION:
- return "destination";
- case DBUS_HEADER_FIELD_SENDER:
- return "sender";
- case DBUS_HEADER_FIELD_SIGNATURE:
- return "signature";
- default:
- return "unknown";
- }
-}
-#endif /* DBUS_BUILD_TESTS */
-
#ifndef DBUS_DISABLE_CHECKS
/** String used in _dbus_return_if_fail macro */
const char *_dbus_return_if_fail_warning_format =
}
#endif /* DBUS_DISABLE_ASSERT */
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
static dbus_bool_t
run_failing_each_malloc (int n_mallocs,
const char *description,
return TRUE;
}
-#endif /* DBUS_BUILD_TESTS */
+#endif /* DBUS_ENABLE_EMBEDDED_TESTS */
/** @} */