After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 770953 - gstclock: segmentation fault when unschedule
gstclock: segmentation fault when unschedule
Status: RESOLVED OBSOLETE
Product: GStreamer
Classification: Platform
Component: gstreamer (core)
1.8.3
Other Linux
: Normal normal
: git master
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2016-09-06 14:39 UTC by Miguel París Díaz
Modified: 2018-11-03 12:36 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
gstclock: Keep weak reference to underlying clock (7.73 KB, patch)
2016-09-06 19:35 UTC, GstBlub
none Details | Review
gstclock: Keep weak reference to underlying clock (7.48 KB, patch)
2016-09-07 14:45 UTC, GstBlub
none Details | Review
gstclock: Keep weak reference to underlying clock (8.83 KB, patch)
2016-09-07 18:18 UTC, GstBlub
none Details | Review
gstclock: Keep weak reference to underlying clock (8.54 KB, patch)
2016-09-08 15:00 UTC, GstBlub
needs-work Details | Review

Description Miguel París Díaz 2016-09-06 14:39:36 UTC
Hello,
I have found a segmentation fault when gst_clock_id_unschedule is called.

Debugging with GDB I found that it is caused in the line [1].
From this info and analysing the code, it seems that gst_clock_entry_new [2] does not increase the ref of the clock used, it just keeps the pointer.
So I suppose that the problem is that the clock has been released when gst_clock_id_unschedule is called.

What do you think about that?

Refs
[1] https://github.com/Kurento/gstreamer/blob/0fb3a083ce04551fbdba7a94f0ac5612515bda67/gst/gstclock.c#L667
[2] https://github.com/Kurento/gstreamer/blob/0fb3a083ce04551fbdba7a94f0ac5612515bda67/gst/gstclock.c#L243
Comment 1 GstBlub 2016-09-06 19:23:26 UTC
Do you still have the gdb stack trace?  I remember seeing something like that, but I don't remember how I got it to happen.
Comment 2 GstBlub 2016-09-06 19:35:23 UTC
Created attachment 334928 [details] [review]
gstclock: Keep weak reference to underlying clock

Can you try with this patch?
Comment 3 Sebastian Dröge (slomo) 2016-09-07 07:01:50 UTC
Comment on attachment 334928 [details] [review]
gstclock: Keep weak reference to underlying clock

While this patch makes sense (except for the change in common/, please omit that :) ), it shouldn't be necessary according to the comments in the clock code.

Question is what and why the clock is gone before the clock ids are gone. This sounds like an element getting rid of the clock but not its clock ids.
Comment 4 Miguel París Díaz 2016-09-07 08:07:51 UTC
Hello,
the patch also makes sense from my point of view.

@slomo, now we are using a data structure to keep the ClockId until we need it, but the Clock is unrefered after creating the ClockId as you can see in the next code.
Without the @GstBlub's patch, should we keep the Clock ref in the data structure until the ClockId is unshceduled?

ClockId creation:
  GstClock *clock;
  clock = gst_system_clock_obtain ();
  init_time = gst_clock_get_time (clock);
  clock_id = gst_clock_new_periodic_id (data->clock, init_time, 2 * GST_SECOND);
  g_object_unref (clock);

Then, when the ClockId is not longer needed:
  gst_clock_id_unschedule (data->clock_id);
  gst_clock_id_unref (data->clock_id);
Comment 5 Sebastian Dröge (slomo) 2016-09-07 08:12:25 UTC
Keeping the clock around is AFAIU how that API is intended to be used (API with a gun to shoot yourself into the feet included *sigh*).

The problem with not keeping the clock around is that you can never be sure if your callback is actually ever going to be called, which is also problematic. OTOH you're not guaranteed that either otherwise (e.g. when an audio clock is used and we're down in PAUSED).

I think the patch makes sense (slightly worried about the overhead of the weak ref) but there also seems to be a bigger problem here
Comment 6 Miguel París Díaz 2016-09-07 08:41:59 UTC
@slomo, thank you for the explanation!!

So, from my point of view:
- Or we include the @GstBlub's patch.
- Or we should update de doc of gst_clock_new_periodic_id and gst_clock_new_single_shot_id

What do you think?
Comment 7 GstBlub 2016-09-07 14:41:49 UTC
(In reply to Sebastian Dröge (slomo) from comment #3)
> Comment on attachment 334928 [details] [review] [review]
> gstclock: Keep weak reference to underlying clock
> 
> While this patch makes sense (except for the change in common/, please omit
> that :) ), it shouldn't be necessary according to the comments in the clock
> code.

Oops, that change was not intentional (switching branches too often I guess)

> Question is what and why the clock is gone before the clock ids are gone.
> This sounds like an element getting rid of the clock but not its clock ids.

Yeah, sounds like an element is doing something wrong, BUT at the same time the Clock IDs should either ref the clock so it never goes away until all IDs are gone, or they should at least hold a weak reference.  I chose the latter as holding a strong reference would change behaviour.  Keeping a week reference handles the incorrect use more gracefully, though at the expense of some overhead.
Comment 8 GstBlub 2016-09-07 14:45:07 UTC
Created attachment 335003 [details] [review]
gstclock: Keep weak reference to underlying clock

Updated the patch.
Comment 9 Sebastian Dröge (slomo) 2016-09-07 16:05:15 UTC
Yes, I think generally having this patch is a good idea. The elements should also be fixed though :)
Comment 10 Sebastian Dröge (slomo) 2016-09-07 16:06:54 UTC
Review of attachment 335003 [details] [review]:

::: gst/gstclock.h
@@ -347,3 @@
- * Get the owner clock of the entry
- */
-#define GST_CLOCK_ENTRY_CLOCK(entry)    ((entry)->clock)

Don't remove public API

@@ +558,3 @@
 gint                    gst_clock_id_compare_func       (gconstpointer id1, gconstpointer id2);
 
+gboolean                gst_clock_id_is_clock           (GstClockID id, GstClock * clock);

Maybe gst_clock_id_belongs_to_clock()? gst_clock_id_get_clock()?
Comment 11 GstBlub 2016-09-07 16:16:34 UTC
(In reply to Sebastian Dröge (slomo) from comment #10)
> Review of attachment 335003 [details] [review] [review]:
> 
> ::: gst/gstclock.h
> @@ -347,3 @@
> - * Get the owner clock of the entry
> - */
> -#define GST_CLOCK_ENTRY_CLOCK(entry)    ((entry)->clock)
> 
> Don't remove public API

The problem with keeping it is that it would have to be change to obtain a strong reference, which means that the user of this API would have to unref it.  I would rather remove this broken API, no one should really be using it anyway.

> 
> @@ +558,3 @@
>  gint                    gst_clock_id_compare_func       (gconstpointer id1,
> gconstpointer id2);
>  
> +gboolean                gst_clock_id_is_clock           (GstClockID id,
> GstClock * clock);
> 
> Maybe gst_clock_id_belongs_to_clock()? gst_clock_id_get_clock()?

How about gst_clock_id_uses_clock()?

We could add gst_clock_id_get_clock() as a replacement for GST_CLOCK_ENTRY_CLOCK(), although the semantics would be slightly different.
Comment 12 GstBlub 2016-09-07 16:23:56 UTC
(In reply to Sebastian Dröge (slomo) from comment #9)
> Yes, I think generally having this patch is a good idea. The elements should
> also be fixed though :)

The question is which element is it?  I know I ran into a crash like this before, but I don't recall if it was my own fault or if it was some gstreamer element.  Maybe Miguel can shed some light.
Comment 13 Sebastian Dröge (slomo) 2016-09-07 16:25:25 UTC
(In reply to GstBlub from comment #11)
> (In reply to Sebastian Dröge (slomo) from comment #10)
> > Review of attachment 335003 [details] [review] [review] [review]:
> > 
> > ::: gst/gstclock.h
> > @@ -347,3 @@
> > - * Get the owner clock of the entry
> > - */
> > -#define GST_CLOCK_ENTRY_CLOCK(entry)    ((entry)->clock)
> > 
> > Don't remove public API
> 
> The problem with keeping it is that it would have to be change to obtain a
> strong reference, which means that the user of this API would have to unref
> it.  I would rather remove this broken API, no one should really be using it
> anyway.

Deprecate this one (and in #ifndef GST_DISABLE_DEPRECATED guards), and add a function that gives a strong ref :)

> > 
> > @@ +558,3 @@
> >  gint                    gst_clock_id_compare_func       (gconstpointer id1,
> > gconstpointer id2);
> >  
> > +gboolean                gst_clock_id_is_clock           (GstClockID id,
> > GstClock * clock);
> > 
> > Maybe gst_clock_id_belongs_to_clock()? gst_clock_id_get_clock()?
> 
> How about gst_clock_id_uses_clock()?

Ack
 
> We could add gst_clock_id_get_clock() as a replacement for
> GST_CLOCK_ENTRY_CLOCK(), although the semantics would be slightly different.

Yes, add a new function for that and deprecate the macro
Comment 14 GstBlub 2016-09-07 16:31:32 UTC
(In reply to Sebastian Dröge (slomo) from comment #13)
> (In reply to GstBlub from comment #11)
> > The problem with keeping it is that it would have to be change to obtain a
> > strong reference, which means that the user of this API would have to unref
> > it.  I would rather remove this broken API, no one should really be using it
> > anyway.
> 
> Deprecate this one (and in #ifndef GST_DISABLE_DEPRECATED guards), and add a
> function that gives a strong ref :)

What should the deprecated macro do?  Leak a reference each time it is called, or return an unsafe pointer to the GstClock (essentially temporarily obtain a strong reference, unreffing it again, and returning the raw pointer)?
Comment 15 Sebastian Dröge (slomo) 2016-09-07 16:41:36 UTC
The same it does now, and potentially crash
Comment 16 GstBlub 2016-09-07 18:18:05 UTC
Created attachment 335014 [details] [review]
gstclock: Keep weak reference to underlying clock

Updated patch.
Comment 17 Miguel París Díaz 2016-09-07 20:07:43 UTC
(In reply to GstBlub from comment #12)

> The question is which element is it?  I know I ran into a crash like this
> before, but I don't recall if it was my own fault or if it was some
> gstreamer element.  Maybe Miguel can shed some light.

In my case it was my fault because I assumed that keeping the clock ref was not needed.
Comment 18 Sebastian Dröge (slomo) 2016-09-08 07:33:55 UTC
Review of attachment 335014 [details] [review]:

::: gst/gstclock.h
@@ +394,3 @@
   gint                  refcount;
   /*< protected >*/
+  GWeakRef               clock;

This will still break ABI: everything currently using GST_CLOCK_ENTRY_CLOCK() would need to be recompiled or would do weird things.

You will have to keep this as is, and add the GWeakRef into the padding at the end, e.g.

union {
  gpointer _gst_reserved[GST_PADDING];
  GWeakRef clock;
} ABI;


And then you can also leave the macro above as is
Comment 19 GstBlub 2016-09-08 15:00:15 UTC
Created attachment 335121 [details] [review]
gstclock: Keep weak reference to underlying clock

Updated the patch once again.
Comment 20 Tim-Philipp Müller 2016-11-11 12:06:55 UTC
Comment on attachment 335121 [details] [review]
gstclock: Keep weak reference to underlying clock

>--- a/gst/gstclock.c
>+++ b/gst/gstclock.c
>@@ -247,7 +247,10 @@ gst_clock_entry_new (GstClock * clock, GstClockTime time,
>       "created entry %p, time %" GST_TIME_FORMAT, entry, GST_TIME_ARGS (time));
> 
>   entry->refcount = 1;
>+#ifndef GST_DISABLE_DEPRECATED
>   entry->clock = clock;
>+#endif
>+  g_weak_ref_init (&entry->ABI.clock, clock);

Not sure this is right, we should keep setting it for backwards compat. I think you probably wanted a

#ifndef GST_REMOVE_DEPRECATED

here instead (and also in the header).

 
> /**
>+ * gst_clock_id_get_clock:
>+ * @id: a #GstClockID
>+ *
>+ * This function returns the underlying clock.
>+ *
>+ * Returns: (transfer full) (nullable): a #GstClock or %NULL when the
>+ *     underlying clock has been freed.  Unref after usage.
>+ *
>+ * MT safe.

Please add a Since: 1.12  here and for uses_clock()
Comment 21 GStreamer system administrator 2018-11-03 12:36:09 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/gstreamer/gstreamer/issues/187.