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 792575 - Switching a lot between pause/playing state, endless hanging of GST_STATE_WAIT inside gst_element_get_state_func
Switching a lot between pause/playing state, endless hanging of GST_STATE_WAI...
Status: RESOLVED OBSOLETE
Product: GStreamer
Classification: Platform
Component: gstreamer (core)
1.12.4
Other Linux
: Normal normal
: git master
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2018-01-16 13:48 UTC by Marie Maurer
Modified: 2018-11-03 12:44 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Logfile of error, error completely at the end of logfile (95.88 KB, application/x-zip-compressed)
2018-01-16 13:48 UTC, Marie Maurer
Details

Description Marie Maurer 2018-01-16 13:48:11 UTC
Created attachment 366884 [details]
Logfile of error, error completely at the end of logfile

I am switching a small playback pipeline (on i.MX6)

splitmuxsrc->h264parse->v4l2h264dec->v4l2sink

again and again from pause to playing and back to pause by keypresses.

Just before setting the pipeline to state PLAYING,
I query the current state (just for debugging) via

GstStateChangeReturn rv;
GstState state;
rv = gst_element_get_state(m_pPipeline, &state, NULL, GST_CLOCK_TIME_NONE);

When pressing the key fast enough or just with the right speed,
the program is hanging. I located the hanging in above code,
especially in function gst_element_get_state.
Adding further debug info it seems it is hanging here
just between debug output "MIDDLE 2a" and "MIDDLE 2b":

/* MT safe */
static GstStateChangeReturn
gst_element_get_state_func (GstElement * element,
    GstState * state, GstState * pending, GstClockTime timeout)
{
  GstStateChangeReturn ret = GST_STATE_CHANGE_FAILURE;
  GstState old_pending;

  fprintf(stderr, "MMMM I am in gst_element_get_state_func START\n");

  GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "getting state, timeout %"
      GST_TIME_FORMAT, GST_TIME_ARGS (timeout));

  GST_OBJECT_LOCK (element);
  ret = GST_STATE_RETURN (element);
  GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "RETURN is %s",
      gst_element_state_change_return_get_name (ret));

  fprintf(stderr, "MMMM I am in gst_element_get_state_func MIDDLE 1\n");

  /* we got an error, report immediately */
  if (ret == GST_STATE_CHANGE_FAILURE)
    goto done;

  /* we got no_preroll, report immediately */
  if (ret == GST_STATE_CHANGE_NO_PREROLL)
    goto done;

  /* no need to wait async if we are not async */
  if (ret != GST_STATE_CHANGE_ASYNC)
    goto done;

  old_pending = GST_STATE_PENDING (element);
  if (old_pending != GST_STATE_VOID_PENDING) {
    gboolean signaled;
    guint32 cookie;

    fprintf(stderr, "MMMM I am in gst_element_get_state_func MIDDLE 2\n");

    /* get cookie to detect state changes during waiting */
    cookie = element->state_cookie;

    GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
        "waiting for element to commit state");

    /* we have a pending state change, wait for it to complete */
    if (timeout != GST_CLOCK_TIME_NONE) {
      gint64 end_time;
      /* make timeout absolute */
      end_time = g_get_monotonic_time () + (timeout / 1000);
      signaled = GST_STATE_WAIT_UNTIL (element, end_time);
    } else {
      fprintf(stderr, "MMMM I am in gst_element_get_state_func MIDDLE 2a\n");
      GST_STATE_WAIT (element);
      fprintf(stderr, "MMMM I am in gst_element_get_state_func MIDDLE 2b\n");
      signaled = TRUE;
    }
...
}

In the beginning of the function gst_element_get_state_func
there is GST_OBJECT_LOCK (element);
Could there be some situation where we lock out the background task
from doing some change of state, but then wait till this background task
is finished?

How to continue analysis? An idea what could go wrong here?

Logfile of gstreamer attached.
Comment 1 Nicolas Dufresne (ndufresne) 2018-01-16 15:06:38 UTC
Can you retest with the tip of 1.12 branch of gstreamer ? There was a regression that was fixed yesterday in relation. See:

https://bugzilla.gnome.org/show_bug.cgi?id=792341
Comment 2 Tim-Philipp Müller 2018-01-16 15:18:04 UTC
And please also post a stack trace of all threads to see where they're stuck ('thread apply all bt' in gdb).
Comment 3 Marie Maurer 2018-01-22 16:18:46 UTC
The problem occurs also with latest version of 1.12 branch.

Stack trace (but I assume, i must enable more debug/symbols?):

(gdb) t a a bt

Thread 114 (Thread 0x41dbb3d0 (LWP 456))

  • #0 syscall
    from /lib/libc.so.6
  • #1 g_cond_wait
    from /usr/lib/libglib-2.0.so.0
  • #2 ??

Thread 112 (Thread 0x371ff3d0 (LWP 454))

  • #0 syscall
    from /lib/libc.so.6
  • #1 g_cond_wait
    from /usr/lib/libglib-2.0.so.0
  • #2 ??

Thread 109 (Thread 0x379ff3d0 (LWP 450))

  • #0 syscall
    from /lib/libc.so.6
  • #1 g_cond_wait
    from /usr/lib/libglib-2.0.so.0
  • #2 ??

After this output, gdb is not reacting anymore...

It happens on an proprietary i.MX6Q platform with linux kernel
Linux buildroot 4.15.0-rc6-20180102-1 #1 SMP PREEMPT Fri Jan 19 16:43:37 CET 2018 armv7l GNU/Linux

Patches of 1.12 manually added:
gst-launch-1.0 version 1.12.4
GStreamer 1.12.4
Unknown package origin
Comment 4 GStreamer system administrator 2018-11-03 12:44:25 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/269.