[vlc-devel] [PATCH] libvlc: dump object types abd names when leaking

Romain Vimont rom1v at videolabs.io
Thu Feb 21 12:47:46 CET 2019


This patch helps a lot many developers (myself included) when a
vlc_object leaks on close. We know where the leak comes from
immediately (of course, we could find it differently with more efforts,
but what's the point?).

This code only exists in debug mode (this is what debug code is for:
help debugging), I see no (convincing) disadvantage, so LGTM.

On Thu, Feb 21, 2019 at 10:24:57AM +0100, Thomas Guillem wrote:
> Comment:
> A lot of developers asked me to propose this patch again. It was previously
> refused because developers could use proper debugging tools. I disagree with
> that assumption. Even with Asan, when the leak assert fail, it will abort()
> without prompting any leaks, so you'll have to edit libvlc.c to remove this
> assert. If your leak was not reproducible, you'll lose a precious information.
> And good luck finding the leak with GDB, you really need to know the internal
> of vlc_object_t to iterate through the different list to get the culprit.
> 
> Commit log:
> 
> In case of a vlc_object_t leak, and if asserts are enabled, the error output
> will be like the following (when leaking intentionally decoder_t objects):
> 
> === vlc_object LEAKS detected ===
>   \ playlist
>   |   \ input
>   |   |   \ decoder avcodec
>   |   |   | decoder faad
>   |   |   | decoder stl
> ---
>  src/libvlc.c | 30 ++++++++++++++++++++++++++++++
>  1 file changed, 30 insertions(+)
> 
> diff --git a/src/libvlc.c b/src/libvlc.c
> index 8e8d2ca8b2..d9ff96de84 100644
> --- a/src/libvlc.c
> +++ b/src/libvlc.c
> @@ -436,6 +436,24 @@ void libvlc_InternalCleanup( libvlc_int_t *p_libvlc )
>  #endif
>  }
>  
> +#ifndef NDEBUG
> +static void DumpObjectLeaks(vlc_object_internals_t *priv, unsigned level)
> +{
> +    bool first = true;
> +    vlc_list_foreach(priv, &priv->children, siblings)
> +    {
> +        vlc_object_t *obj = vlc_externals(priv);
> +        for (unsigned i = 0; i < level; i++)
> +            fprintf(stderr, "  %s ", first && i == level -1 ? "\\" : "|");
> +        char *name = vlc_object_get_name(obj);
> +        fprintf(stderr, "%s %s\n", vlc_object_typename(obj), name ? name : "");
> +        free(name);
> +        DumpObjectLeaks(priv, level + 1);
> +        first = false;
> +    }
> +}
> +#endif
> +
>  /**
>   * Destroy everything.
>   * This function requests the running threads to finish, waits for their
> @@ -449,6 +467,18 @@ void libvlc_InternalDestroy( libvlc_int_t *p_libvlc )
>  
>      vlc_ExitDestroy( &priv->exit );
>  
> +#ifndef NDEBUG
> +    {
> +        vlc_object_internals_t *internal = vlc_internals(p_libvlc);
> +        if (atomic_load(&internal->refs) != 1)
> +        {
> +            vlc_mutex_lock(&internal->tree_lock);
> +            fprintf(stderr, "=== vlc_object LEAKS detected ===\n");
> +            DumpObjectLeaks(internal, 1);
> +            vlc_mutex_unlock(&internal->tree_lock);
> +        }
> +    }
> +#endif
>      assert( atomic_load(&(vlc_internals(p_libvlc)->refs)) == 1 );
>      vlc_object_release( p_libvlc );
>  }
> -- 
> 2.20.1
> 
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel


More information about the vlc-devel mailing list