mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-08-03 07:53:39 +02:00
Merge branch 'wip/3v1n0/sanitizer-memory-fixes' into 'main'
Memory sanitizer fixes See merge request GNOME/glib!4484
This commit is contained in:
@@ -539,7 +539,7 @@ test_connection_signal_handler (GDBusConnection *connection,
|
||||
|
||||
/* We defer quitting to a G_PRIORITY_DEFAULT_IDLE function so other queued signal
|
||||
* callbacks have a chance to run first. They get dispatched with a higher priority
|
||||
* of G_PIORITY_DEFAULT, so as long as the queue is non-empty g_main_loop_quit won't
|
||||
* of G_PRIORITY_DEFAULT, so as long as the queue is non-empty g_main_loop_quit won't
|
||||
* run
|
||||
*/
|
||||
g_idle_add_once ((GSourceOnceFunc) g_main_loop_quit, loop);
|
||||
|
@@ -1960,6 +1960,17 @@ test_threaded_unregistration_iteration (gboolean subtree)
|
||||
g_clear_object (&call_result);
|
||||
g_clear_object (&data.connection);
|
||||
|
||||
/* We defer quitting to a G_PRIORITY_DEFAULT_IDLE function so other queued
|
||||
* signal callbacks have a chance to run first.
|
||||
* In particular we want to ensure that all calls to on_object_unregistered()
|
||||
* are delivered here before we end this function, so that there won't be any
|
||||
* invalid stack access.
|
||||
* They get dispatched with a higher priority (G_PRIORITY_DEFAULT), so as
|
||||
* long as the queue is non-empty g_main_loop_quit won't run
|
||||
*/
|
||||
g_idle_add_once ((GSourceOnceFunc) g_main_loop_quit, loop);
|
||||
g_main_loop_run (loop);
|
||||
|
||||
return unregistration_was_first;
|
||||
}
|
||||
|
||||
|
@@ -219,6 +219,7 @@ main (int argc, char **argv)
|
||||
g_fprintf (stderr, "%s\n", message);
|
||||
g_free (message);
|
||||
gi_ir_parser_free (parser);
|
||||
g_error_free (error);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -229,6 +230,7 @@ main (int argc, char **argv)
|
||||
|
||||
{
|
||||
GITypelib *typelib = NULL;
|
||||
int write_successful;
|
||||
|
||||
if (shlibs)
|
||||
{
|
||||
@@ -246,10 +248,14 @@ main (int argc, char **argv)
|
||||
g_error (_("Invalid typelib for module ‘%s’: %s"),
|
||||
module->name, error->message);
|
||||
|
||||
if (!write_out_typelib (NULL, typelib))
|
||||
return 1;
|
||||
|
||||
write_successful = write_out_typelib (NULL, typelib);
|
||||
g_clear_pointer (&typelib, gi_typelib_unref);
|
||||
|
||||
if (!write_successful)
|
||||
{
|
||||
gi_ir_parser_free (parser);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
g_debug ("[building] done");
|
||||
|
@@ -2312,7 +2312,7 @@ end_type_top (ParseContext *ctx)
|
||||
if (!ctx->type_parameters)
|
||||
goto out;
|
||||
|
||||
typenode = (GIIrNodeType*)ctx->type_parameters->data;
|
||||
typenode = (GIIrNodeType *) g_steal_pointer (&ctx->type_parameters->data);
|
||||
|
||||
/* Default to pointer for unspecified containers */
|
||||
if (typenode->tag == GI_TYPE_TAG_ARRAY ||
|
||||
@@ -2336,32 +2336,32 @@ end_type_top (ParseContext *ctx)
|
||||
case GI_IR_NODE_PARAM:
|
||||
{
|
||||
GIIrNodeParam *param = (GIIrNodeParam *)ctx->current_typed;
|
||||
param->type = typenode;
|
||||
param->type = g_steal_pointer (&typenode);
|
||||
}
|
||||
break;
|
||||
case GI_IR_NODE_FIELD:
|
||||
{
|
||||
GIIrNodeField *field = (GIIrNodeField *)ctx->current_typed;
|
||||
field->type = typenode;
|
||||
field->type = g_steal_pointer (&typenode);
|
||||
}
|
||||
break;
|
||||
case GI_IR_NODE_PROPERTY:
|
||||
{
|
||||
GIIrNodeProperty *property = (GIIrNodeProperty *) ctx->current_typed;
|
||||
property->type = typenode;
|
||||
property->type = g_steal_pointer (&typenode);
|
||||
}
|
||||
break;
|
||||
case GI_IR_NODE_CONSTANT:
|
||||
{
|
||||
GIIrNodeConstant *constant = (GIIrNodeConstant *)ctx->current_typed;
|
||||
constant->type = typenode;
|
||||
constant->type = g_steal_pointer (&typenode);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
g_printerr("current node is %d\n", CURRENT_NODE (ctx)->type);
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
g_list_free (ctx->type_parameters);
|
||||
g_list_free_full (ctx->type_parameters, (GDestroyNotify) gi_ir_node_free);
|
||||
|
||||
out:
|
||||
ctx->type_depth = 0;
|
||||
@@ -2377,7 +2377,7 @@ end_type_recurse (ParseContext *ctx)
|
||||
|
||||
parent = (GIIrNodeType *) ((GList*)ctx->type_stack->data)->data;
|
||||
if (ctx->type_parameters)
|
||||
param = (GIIrNodeType *) ctx->type_parameters->data;
|
||||
param = (GIIrNodeType *) g_steal_pointer (&ctx->type_parameters->data);
|
||||
|
||||
if (parent->tag == GI_TYPE_TAG_ARRAY ||
|
||||
parent->tag == GI_TYPE_TAG_GLIST ||
|
||||
@@ -2386,7 +2386,7 @@ end_type_recurse (ParseContext *ctx)
|
||||
g_assert (param != NULL);
|
||||
|
||||
if (parent->parameter_type1 == NULL)
|
||||
parent->parameter_type1 = param;
|
||||
parent->parameter_type1 = g_steal_pointer (¶m);
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
@@ -2395,13 +2395,14 @@ end_type_recurse (ParseContext *ctx)
|
||||
g_assert (param != NULL);
|
||||
|
||||
if (parent->parameter_type1 == NULL)
|
||||
parent->parameter_type1 = param;
|
||||
parent->parameter_type1 = g_steal_pointer (¶m);
|
||||
else if (parent->parameter_type2 == NULL)
|
||||
parent->parameter_type2 = param;
|
||||
parent->parameter_type2 = g_steal_pointer (¶m);
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
g_list_free (ctx->type_parameters);
|
||||
g_clear_pointer ((GIIrNode **) ¶m, gi_ir_node_free);
|
||||
g_list_free_full (ctx->type_parameters, (GDestroyNotify) gi_ir_node_free);
|
||||
ctx->type_parameters = (GList *)ctx->type_stack->data;
|
||||
ctx->type_stack = g_list_delete_link (ctx->type_stack, ctx->type_stack);
|
||||
}
|
||||
|
@@ -123,12 +123,19 @@ g_bytes_new (gconstpointer data,
|
||||
{
|
||||
g_return_val_if_fail (data != NULL || size == 0, NULL);
|
||||
|
||||
if (data == NULL || size == 0)
|
||||
{
|
||||
g_assert (data != NULL || size == 0);
|
||||
|
||||
return g_bytes_new_with_free_func (NULL, size, NULL, NULL);
|
||||
}
|
||||
|
||||
if (size <= G_BYTES_MAX_INLINE)
|
||||
{
|
||||
GBytesInline *bytes;
|
||||
|
||||
bytes = g_malloc (sizeof *bytes + size);
|
||||
bytes->bytes.data = (data != NULL && size > 0) ? bytes->inline_data : NULL;
|
||||
bytes->bytes.data = bytes->inline_data;
|
||||
bytes->bytes.size = size;
|
||||
bytes->bytes.free_func = NULL;
|
||||
bytes->bytes.user_data = NULL;
|
||||
|
@@ -26,6 +26,7 @@
|
||||
#include "garray.h"
|
||||
#include "genviron.h"
|
||||
#include "ghash.h"
|
||||
#include "glib-private.h"
|
||||
#include "gmessages.h"
|
||||
#include "gstrfuncs.h"
|
||||
#include "gthread.h"
|
||||
@@ -807,6 +808,7 @@ g_get_language_names_with_category (const gchar *category_name)
|
||||
cache = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
g_free, language_names_cache_free);
|
||||
g_private_set (&cache_private, cache);
|
||||
g_ignore_leak (cache);
|
||||
}
|
||||
|
||||
languages = guess_category_value (category_name);
|
||||
@@ -835,6 +837,7 @@ g_get_language_names_with_category (const gchar *category_name)
|
||||
name_cache->languages = g_strdup (languages);
|
||||
name_cache->language_names = (gchar **) g_ptr_array_free (array, FALSE);
|
||||
g_hash_table_insert (cache, g_strdup (category_name), name_cache);
|
||||
g_ignore_leak (name_cache);
|
||||
}
|
||||
|
||||
return (const gchar * const *) name_cache->language_names;
|
||||
|
@@ -100,7 +100,7 @@ g_leak_sanitizer_is_supported (void)
|
||||
#if defined (_GLIB_ADDRESS_SANITIZER)
|
||||
return TRUE;
|
||||
#elif defined (HAS_DYNAMIC_ASAN_LOADING)
|
||||
return __lsan_enable != NULL && __lsan_ignore_object != NULL;
|
||||
return G_UNLIKELY (__lsan_enable != NULL && __lsan_ignore_object != NULL);
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
@@ -122,7 +122,7 @@ g_ignore_leak (gconstpointer p)
|
||||
if (p != NULL)
|
||||
__lsan_ignore_object (p);
|
||||
#elif defined (HAS_DYNAMIC_ASAN_LOADING)
|
||||
if (p != NULL && __lsan_ignore_object != NULL)
|
||||
if (G_LIKELY (p != NULL) && G_UNLIKELY (__lsan_ignore_object != NULL))
|
||||
__lsan_ignore_object (p);
|
||||
#endif
|
||||
}
|
||||
@@ -166,7 +166,7 @@ g_begin_ignore_leaks (void)
|
||||
#if defined (_GLIB_ADDRESS_SANITIZER)
|
||||
__lsan_disable ();
|
||||
#elif defined (HAS_DYNAMIC_ASAN_LOADING)
|
||||
if (__lsan_disable != NULL)
|
||||
if (G_UNLIKELY (__lsan_disable != NULL))
|
||||
__lsan_disable ();
|
||||
#endif
|
||||
}
|
||||
@@ -183,7 +183,7 @@ g_end_ignore_leaks (void)
|
||||
#if defined (_GLIB_ADDRESS_SANITIZER)
|
||||
__lsan_enable ();
|
||||
#elif defined (HAS_DYNAMIC_ASAN_LOADING)
|
||||
if (__lsan_enable != NULL)
|
||||
if (G_UNLIKELY (__lsan_enable != NULL))
|
||||
__lsan_enable ();
|
||||
#endif
|
||||
}
|
||||
|
@@ -2778,6 +2778,8 @@ should_drop_message (GLogLevelFlags log_level,
|
||||
|
||||
if (log_domain == NULL)
|
||||
{
|
||||
log_domain_length = 0;
|
||||
|
||||
for (i = 0; i < n_fields; i++)
|
||||
{
|
||||
if (g_strcmp0 (fields[i].key, "GLIB_DOMAIN") == 0)
|
||||
|
@@ -40,6 +40,7 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "glib-private.h"
|
||||
#include "gthread.h"
|
||||
#include "gthreadprivate.h"
|
||||
|
||||
@@ -505,10 +506,11 @@ static GPrivate g_thread_specific_private = G_PRIVATE_INIT (g_thread_cleanup
|
||||
*
|
||||
* Sets the thread local variable @key to have a newly-allocated and zero-filled
|
||||
* value of given @size, and returns a pointer to that memory. Allocations made
|
||||
* using this API will be suppressed in valgrind: it is intended to be used for
|
||||
* one-time allocations which are known to be leaked, such as those for
|
||||
* per-thread initialisation data. Otherwise, this function behaves the same as
|
||||
* g_private_set().
|
||||
* using this API will be suppressed in valgrind (when the GLib default
|
||||
* suppression file, `glib.supp`, is used) and leak sanitizer: it is intended to
|
||||
* be used for one-time allocations which are known to be leaked, such as those
|
||||
* for per-thread initialisation data. Otherwise, this function behaves the same
|
||||
* as g_private_set().
|
||||
*
|
||||
* Returns: (transfer full): new thread-local heap allocation of size @size
|
||||
* Since: 2.60
|
||||
@@ -520,6 +522,7 @@ g_private_set_alloc0 (GPrivate *key,
|
||||
{
|
||||
gpointer allocated = g_malloc0 (size);
|
||||
|
||||
g_ignore_leak (allocated);
|
||||
g_private_set (key, allocated);
|
||||
|
||||
return g_steal_pointer (&allocated);
|
||||
|
@@ -1415,6 +1415,8 @@ void
|
||||
g_variant_store (GVariant *value,
|
||||
gpointer data)
|
||||
{
|
||||
g_return_if_fail (data != NULL);
|
||||
|
||||
g_variant_lock (value);
|
||||
|
||||
if (value->state & STATE_SERIALISED)
|
||||
|
@@ -6187,12 +6187,16 @@ g_variant_byteswap (GVariant *value)
|
||||
GVariantTypeInfo *type_info;
|
||||
guint alignment;
|
||||
GVariant *new;
|
||||
gsize size = 0;
|
||||
|
||||
type_info = g_variant_get_type_info (value);
|
||||
|
||||
g_variant_type_info_query (type_info, &alignment, NULL);
|
||||
|
||||
if (alignment && g_variant_is_normal_form (value))
|
||||
if (alignment)
|
||||
size = g_variant_get_size (value);
|
||||
|
||||
if (size > 0 && g_variant_is_normal_form (value))
|
||||
{
|
||||
/* (potentially) contains multi-byte numeric data, but is also already in
|
||||
* normal form so we can use a faster byteswapping codepath on the
|
||||
@@ -6201,7 +6205,7 @@ g_variant_byteswap (GVariant *value)
|
||||
GBytes *bytes;
|
||||
|
||||
serialised.type_info = g_variant_get_type_info (value);
|
||||
serialised.size = g_variant_get_size (value);
|
||||
serialised.size = size;
|
||||
serialised.data = g_malloc (serialised.size);
|
||||
serialised.depth = g_variant_get_depth (value);
|
||||
serialised.ordered_offsets_up_to = G_MAXSIZE; /* operating on the normal form */
|
||||
|
@@ -2327,7 +2327,15 @@ test_byteswap (void)
|
||||
* often makes something non-normal but still readable. */
|
||||
three_size_copy = three.size + 1;
|
||||
three_data_copy = g_malloc (three_size_copy);
|
||||
memcpy (three_data_copy, three.data, three.size);
|
||||
if (three.data)
|
||||
{
|
||||
g_assert_cmpuint (three.size, !=, 0);
|
||||
memcpy (three_data_copy, three.data, three.size);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_assert_cmpuint (three.size, ==, 0);
|
||||
}
|
||||
three_data_copy[three.size] = '\0';
|
||||
|
||||
three_variant = g_variant_new_from_data (G_VARIANT_TYPE (g_variant_type_info_get_type_string (three.type_info)),
|
||||
@@ -2367,6 +2375,19 @@ test_byteswaps (void)
|
||||
g_variant_type_info_assert_no_infos ();
|
||||
}
|
||||
|
||||
static void
|
||||
test_byteswap_zero_sized (void)
|
||||
{
|
||||
GVariant *variant;
|
||||
GVariant *swapped;
|
||||
|
||||
variant = g_variant_new_from_data (G_VARIANT_TYPE_STRING, NULL, 0, TRUE, NULL, NULL);
|
||||
swapped = g_variant_byteswap (variant);
|
||||
|
||||
g_variant_unref (variant);
|
||||
g_variant_unref (swapped);
|
||||
}
|
||||
|
||||
static void
|
||||
test_serialiser_children (void)
|
||||
{
|
||||
@@ -5939,6 +5960,7 @@ main (int argc, char **argv)
|
||||
g_test_add_func ("/gvariant/serialiser/variant", test_variants);
|
||||
g_test_add_func ("/gvariant/serialiser/strings", test_strings);
|
||||
g_test_add_func ("/gvariant/serialiser/byteswap", test_byteswaps);
|
||||
g_test_add_func ("/gvariant/serialiser/byteswap/zero-sized", test_byteswap_zero_sized);
|
||||
g_test_add_func ("/gvariant/serialiser/children", test_serialiser_children);
|
||||
|
||||
for (i = 1; i <= 20; i += 4)
|
||||
|
Reference in New Issue
Block a user