From c66586a5445aa3405403ca47ee37db7a7bd64481 Mon Sep 17 00:00:00 2001 From: =?utf8?q?R=C3=A9mi=20Denis-Courmont?= Date: Thu, 28 Jan 2010 22:03:14 +0200 Subject: [PATCH] Warn about reparented object when debugging --- src/libvlc.h | 1 + src/misc/objects.c | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/libvlc.h b/src/libvlc.h index 97e5dc182f..9949928a68 100644 --- a/src/libvlc.h +++ b/src/libvlc.h @@ -183,6 +183,7 @@ struct vlc_object_internals vlc_object_internals_t *next; /* next sibling */ vlc_object_internals_t *prev; /* previous sibling */ vlc_object_internals_t *first; /* first child */ + vlc_object_t *old_parent; }; #define ZOOM_SECTION N_("Zoom") diff --git a/src/misc/objects.c b/src/misc/objects.c index 7d5570fa0f..fb1dc399b4 100644 --- a/src/misc/objects.c +++ b/src/misc/objects.c @@ -154,6 +154,9 @@ void *__vlc_custom_create( vlc_object_t *p_this, size_t i_size, p_priv->b_thread = false; p_new->p_parent = NULL; p_priv->first = NULL; +#ifndef NDEBUG + p_priv->old_parent = NULL; +#endif /* Initialize mutexes and condvars */ vlc_mutex_init( &p_priv->var_lock ); @@ -612,6 +615,20 @@ void __vlc_object_attach( vlc_object_t *p_this, vlc_object_t *p_parent ) priv->prev = NULL; vlc_object_hold (p_parent); libvlc_lock (p_this->p_libvlc); +#ifndef NDEBUG + /* Reparenting an object carries a risk of invalid access to the parent, + * from another thread. This can happen when inheriting a variable, or + * through any direct access to vlc_object_t.p_parent. Also, reparenting + * brings a functional bug, whereby the reparented object uses incorrect + * old values for inherited variables (as the new parent may have different + * variable values, especially if it is an input). + * Note that the old parent may be already destroyed. + * So its pointer must not be dereferenced. + */ + if (priv->old_parent) + msg_Info (p_this, "Reparenting an object is dangerous (%p -> %p)!", + priv->old_parent, p_parent); +#endif /* Attach the parent to its child */ assert (!p_this->p_parent); @@ -642,6 +659,9 @@ static void vlc_object_detach_unlocked (vlc_object_t *p_this) priv->next->prev = priv->prev; /* Remove p_this's parent */ +#ifndef NDEBUG + priv->old_parent = p_this->p_parent; +#endif p_this->p_parent = NULL; } -- 2.39.2