GNOME Bugzilla – Bug 735952
videorate: GstStructure refcount critical message
Last modified: 2014-09-21 14:40:55 UTC
When using videorate, I have encountered a 'critical' error. (<unknown>:1327): GStreamer-CRITICAL **: void gst_structure_free(GstStructure *): assertion `GST_STRUCTURE_REFCOUNT (structure) == NULL' failed Below is a little bit of GST_CAPS:5 and the thread backtrace: 0:00:11.767961000 1327 0x106076680 DEBUG GST_CAPS gstreamer/gst/gstutils.c:2822:GstCaps *gst_pad_peer_query_caps(GstPad *, GstCaps *):<source-video-scale-0:src> peer query returned video/x-raw, width=(int)640, height=(int)480, framerate=(fraction)30/1, format=(string)BGRA; video/x-raw, width=(int)640, height=(int)480, framerate=(fraction)[ 0/1, 30/1 ], format=(string)BGRA; video/x-raw, width=(int)640, height=(int)480, format=(string)UYVY, framerate=(fraction)30/1; video/x-raw, width=(int)640, height=(int)480, format=(string)UYVY, framerate=(fraction)[ 0/1, 30/1 ]; video/x-raw, width=(int)640, height=(int)480, format=(string)YUY2, framerate=(fraction)30/1; video/x-raw, width=(int)640, height=(int)480, format=(string)YUY2, framerate=(fraction)[ 0/1, 30/1 ]; video/x-raw, width=(int)640, height=(int)480, format=(string)NV12, framerate=(fraction)30/1; video/x-raw, width=(int)640, height=(int)480, format=(string)NV12, framerate=(fraction)[ 0/1, 30/1 ] 0:00:11.768940000 1327 0x105808d20 DEBUG GST_CAPS gstreamer/gst/gstutils.c:2769:GstCaps *gst_pad_query_caps(GstPad *, GstCaps *):<local-video-capture-source-bin-0:src_0_0> get pad caps with filter (NULL) 0:00:11.768930000 1327 0x106076680 DEBUG GST_CAPS gstreamer/gst/gstutils.c:2822:GstCaps *gst_pad_peer_query_caps(GstPad *, GstCaps *):<source-video-rate-0:src> peer query returned video/x-raw, width=(int)640, height=(int)480, framerate=(fraction)30/1, format=(string)BGRA; video/x-raw, width=(int)640, height=(int)480, framerate=(fraction)[ 0/1, 30/1 ], format=(string)BGRA; video/x-raw, width=(int)640, height=(int)480, format=(string)UYVY, framerate=(fraction)30/1; video/x-raw, width=(int)640, height=(int)480, format=(string)UYVY, framerate=(fraction)[ 0/1, 30/1 ]; video/x-raw, width=(int)640, height=(int)480, format=(string)YUY2, framerate=(fraction)30/1; video/x-raw, width=(int)640, height=(int)480, format=(string)YUY2, framerate=(fraction)[ 0/1, 30/1 ]; video/x-raw, width=(int)640, height=(int)480, format=(string)NV12, framerate=(fraction)30/1; video/x-raw, width=(int)640, height=(int)480, format=(string)NV12, framerate=(fraction)[ 0/1, 30/1 ] 0:00:11.768975000 1327 0x105808d20 DEBUG GST_CAPS gstreamer/gst/gstpad.c:2964:gboolean gst_pad_query_caps_default(GstPad *, GstQuery *):<local-video-capture-source-bin-0:src_0_0> query caps caps query: 0x1060766d0, GstQueryCaps, filter=(GstCaps)"NULL", caps=(GstCaps)"NULL"; (<unknown>:1327): GStreamer-CRITICAL **: void gst_structure_free(GstStructure *): assertion `GST_STRUCTURE_REFCOUNT (structure) == NULL' failed Process 1327 stopped * thread #27: tid = 0xe5ea4d, 0x0000000100ce5bd5 daemon`g_logv + 1397, stop reason = EXC_BREAKPOINT (code=EXC_I386_BPT, subcode=0x0) frame #0: 0x0000000100ce5bd5 daemon`g_logv + 1397 daemon`g_logv + 1397: -> 0x100ce5bd5: jmpq 0x100ce5bdf ; g_logv + 1407 0x100ce5bda: callq 0x100fcea12 ; symbol stub for: abort 0x100ce5bdf: jmpq 0x100ce5be4 ; g_logv + 1412 0x100ce5be4: leaq 0x228f8a5(%rip), %rdi ; g_log_depth (lldb) thread backtrace * thread #27: tid = 0xe5ea4d, 0x0000000100ce5bd5 daemon`g_logv + 1397, stop reason = EXC_BREAKPOINT (code=EXC_I386_BPT, subcode=0x0) * frame #0: 0x0000000100ce5bd5 daemon`g_logv + 1397 frame #1: 0x0000000100ce5629 daemon`g_log + 361 frame #2: 0x0000000100ce65f0 daemon`g_return_if_fail_warning + 64 frame #3: 0x0000000100b25cc9 daemon`gst_structure_free(structure=0x000000010594c300) + 121 at gststructure.c:376 frame #4: 0x0000000100aacf3a daemon`gst_caps_merge_structure(caps=0x0000000104804590, structure=0x000000010594c300) + 522 at gstcaps.c:706 frame #5: 0x00000001008db988 daemon`gst_video_rate_transform_caps(trans=0x0000000106080800, direction=GST_PAD_SRC, caps=0x0000000104818850, filter=0x00000001048180f0) + 1064 at gstvideorate.c:434 frame #6: 0x0000000100a76c60 daemon`gst_base_transform_transform_caps(trans=0x0000000106080800, direction=GST_PAD_SRC, caps=0x0000000104818850, filter=0x00000001048180f0) + 304 at gstbasetransform.c:523 frame #7: 0x0000000100a7a15e daemon`gst_base_transform_query_caps(trans=0x0000000106080800, pad=0x00000001038f7af0, filter=0x00000001048180f0) + 1166 at gstbasetransform.c:732 frame #8: 0x0000000100a77762 daemon`gst_base_transform_default_query(trans=0x0000000106080800, direction=GST_PAD_SINK, query=0x0000000104818320) + 1154 at gstbasetransform.c:1535 frame #9: 0x00000001008def53 daemon`gst_video_rate_query(trans=0x0000000106080800, direction=GST_PAD_SINK, query=0x0000000104818320) + 3059 at gstvideorate.c:854 frame #10: 0x0000000100a73b7f daemon`gst_base_transform_query(pad=0x00000001038f7af0, parent=0x0000000106080800, query=0x0000000104818320) + 95 at gstbasetransform.c:1561 frame #11: 0x0000000100af4c7a daemon`gst_pad_query(pad=0x00000001038f7af0, query=0x0000000104818320) + 1242 at gstpad.c:3584 frame #12: 0x0000000100af5dfd daemon`gst_pad_peer_query(pad=0x00000001038f5d80, query=0x0000000104818320) + 1197 at gstpad.c:3715 frame #13: 0x0000000100b4a467 daemon`query_caps_func(pad=0x00000001038f5d80, data=0x0000000108a873e0) + 39 at gstutils.c:2488 frame #14: 0x0000000100af3081 daemon`gst_pad_forward(pad=0x00000001038f5b50, forward=0x0000000100b4a440, user_data=0x0000000108a873e0) + 721 at gstpad.c:2796 frame #15: 0x0000000100b4a3ba daemon`gst_pad_proxy_query_caps(pad=0x00000001038f5b50, query=0x0000000104818320) + 874 at gstutils.c:2538 frame #16: 0x0000000100af3cfc daemon`gst_pad_query_caps_default(pad=0x00000001038f5b50, query=0x0000000104818320) + 156 at gstpad.c:2968 frame #17: 0x0000000100af381b daemon`gst_pad_query_default(pad=0x00000001038f5b50, parent=0x00000001038f0c20, query=0x0000000104818320) + 571 at gstpad.c:3079 frame #18: 0x00000001006920c6 daemon`gst_queue_handle_sink_query(pad=0x00000001038f5b50, parent=0x00000001038f0c20, query=0x0000000104818320) + 1286 at gstqueue.c:872 frame #19: 0x0000000100af4c7a daemon`gst_pad_query(pad=0x00000001038f5b50, query=0x0000000104818320) + 1242 at gstpad.c:3584 frame #20: 0x0000000100af5dfd daemon`gst_pad_peer_query(pad=0x000000010607a010, query=0x0000000104818320) + 1197 at gstpad.c:3715 frame #21: 0x0000000100b4a467 daemon`query_caps_func(pad=0x000000010607a010, data=0x0000000108a87d80) + 39 at gstutils.c:2488 frame #22: 0x0000000100af3081 daemon`gst_pad_forward(pad=0x00000001050a78f0, forward=0x0000000100b4a440, user_data=0x0000000108a87d80) + 721 at gstpad.c:2796 frame #23: 0x0000000100b4a3ba daemon`gst_pad_proxy_query_caps(pad=0x00000001050a78f0, query=0x0000000104818320) + 874 at gstutils.c:2538 frame #24: 0x0000000100af3cfc daemon`gst_pad_query_caps_default(pad=0x00000001050a78f0, query=0x0000000104818320) + 156 at gstpad.c:2968 frame #25: 0x0000000100af381b daemon`gst_pad_query_default(pad=0x00000001050a78f0, parent=0x000000010486ae70, query=0x0000000104818320) + 571 at gstpad.c:3079 frame #26: 0x00000001006ac9fa daemon`gst_tee_sink_query(pad=0x00000001050a78f0, parent=0x000000010486ae70, query=0x0000000104818320) + 42 at gsttee.c:551 frame #27: 0x0000000100af4c7a daemon`gst_pad_query(pad=0x00000001050a78f0, query=0x0000000104818320) + 1242 at gstpad.c:3584 frame #28: 0x0000000100af5dfd daemon`gst_pad_peer_query(pad=0x00000001050a76c0, query=0x0000000104818320) + 1197 at gstpad.c:3715 frame #29: 0x0000000100b4b110 daemon`gst_pad_peer_query_caps(pad=0x00000001050a76c0, filter=0x00000001048180f0) + 432 at gstutils.c:2818 frame #30: 0x0000000100a79fe3 daemon`gst_base_transform_query_caps(trans=0x00000001050b8390, pad=0x00000001050a7490, filter=0x00000001048182d0) + 787 at gstbasetransform.c:715 frame #31: 0x0000000100a77762 daemon`gst_base_transform_default_query(trans=0x00000001050b8390, direction=GST_PAD_SINK, query=0x00000001048180a0) + 1154 at gstbasetransform.c:1535 frame #32: 0x0000000100a73b7f daemon`gst_base_transform_query(pad=0x00000001050a7490, parent=0x00000001050b8390, query=0x00000001048180a0) + 95 at gstbasetransform.c:1561 frame #33: 0x0000000100af4c7a daemon`gst_pad_query(pad=0x00000001050a7490, query=0x00000001048180a0) + 1242 at gstpad.c:3584 frame #34: 0x0000000100af5dfd daemon`gst_pad_peer_query(pad=0x00000001050a7260, query=0x00000001048180a0) + 1197 at gstpad.c:3715 frame #35: 0x0000000100b4b110 daemon`gst_pad_peer_query_caps(pad=0x00000001050a7260, filter=0x00000001048182d0) + 432 at gstutils.c:2818 frame #36: 0x0000000100a6eb3e daemon`gst_base_src_default_negotiate(basesrc=0x000000010487a000) + 238 at gstbasesrc.c:3182 frame #37: 0x0000000100a6976c daemon`gst_base_src_negotiate(basesrc=0x000000010487a000) + 140 at gstbasesrc.c:3246 frame #38: 0x0000000100a68505 daemon`gst_base_src_loop(pad=0x00000001050a7260) + 277 at gstbasesrc.c:2683 frame #39: 0x0000000100b3b1ab daemon`gst_task_func(task=0x00000001048177e0) + 747 at gsttask.c:317 frame #40: 0x0000000100b3bdc7 daemon`default_func(tdata=0x000000010371b740, pool=0x0000000103812010) + 71 at gsttaskpool.c:68 frame #41: 0x0000000100d0df60 daemon`g_thread_pool_thread_proxy + 128 frame #42: 0x0000000100d0d0a8 daemon`g_thread_proxy + 152 frame #43: 0x00007fff889e5899 libsystem_pthread.dylib`_pthread_body + 138 frame #44: 0x00007fff889e572a libsystem_pthread.dylib`_pthread_start + 137
How can this be reproduced? Do you have a valgrind log?
I was trying to find a nice way to reproduce with a simple gst-launch pipeline like this: gst-launch-1.0 videotestsrc ! "video/x-raw, width=640, height=480, format=UYVY, framerate=(fraction)[ 0/1, 30/1 ]" ! videorate ! fakesink But it seems the caps grammar barfs on that: 0:00:00.025742000 20339 0x1006b5c90 ERROR GST_PIPELINE ./grammar.y:796:int priv_gst_parse_yyparse(void *, graph_t *): could not parse caps "video/x-raw,\ width=640,\ height=480,\ format=UYVY,\ framerate=(fraction)[\ 0/1,\ 30/1\ ]" WARNING: erroneous pipeline: could not parse caps "video/x-raw,\ width=640,\ height=480,\ format=UYVY,\ framerate=(fraction)[\ 0/1,\ 30/1\ ]" I suspect it's the framerate list but the backtrace should be useful in identifying the code at least.
I just got a crash from the same issue: (<unknown>:27061): GStreamer-CRITICAL **: void gst_structure_free(GstStructure *): assertion `GST_STRUCTURE_REFCOUNT (structure) == NULL' failed daemon(27061,0x108a07000) malloc: *** error for object 0x10378cd00: pointer being freed was not allocated *** set a breakpoint in malloc_error_break to debug Process 27061 stopped * thread #30: tid = 0xe78a55, 0x00007fff91f39866 libsystem_kernel.dylib`__pthread_kill + 10, stop reason = signal SIGABRT frame #0: 0x00007fff91f39866 libsystem_kernel.dylib`__pthread_kill + 10 libsystem_kernel.dylib`__pthread_kill + 10: -> 0x7fff91f39866: jae 0x7fff91f39870 ; __pthread_kill + 20 0x7fff91f39868: movq %rax, %rdi 0x7fff91f3986b: jmpq 0x7fff91f36175 ; cerror_nocancel 0x7fff91f39870: ret (lldb) thread backtrace * thread #30: tid = 0xe78a55, 0x00007fff91f39866 libsystem_kernel.dylib`__pthread_kill + 10, stop reason = signal SIGABRT * frame #0: 0x00007fff91f39866 libsystem_kernel.dylib`__pthread_kill + 10 frame #1: 0x00007fff889e635c libsystem_pthread.dylib`pthread_kill + 92 frame #2: 0x00007fff87ca9b1a libsystem_c.dylib`abort + 125 frame #3: 0x00007fff8e48907f libsystem_malloc.dylib`free + 411 frame #4: 0x0000000100ce45c7 daemon`g_free + 39 frame #5: 0x0000000100c9fcc4 daemon`array_free + 148 frame #6: 0x0000000100c9fdcd daemon`g_array_free + 109 frame #7: 0x0000000100b25b36 daemon`gst_structure_free(structure=0x0000000103786280) + 278 at gststructure.c:386 frame #8: 0x0000000100aacd0a daemon`gst_caps_merge_structure(caps=0x000000010487a940, structure=0x0000000103786280) + 522 at gstcaps.c:706 ... From: daemon(27061,0x108a07000) malloc: *** error for object 0x10378cd00: pointer being freed was not allocated It looks like it could be trying to free a pointer that has already been freed or something.
Hi Robert/Sebastian, I was able to reproduce the issue with the following launch command gst-launch-1.0 videotestsrc ! "video/x-raw, width=640, height=480, format=UYVY,framerate=30/1" ! videorate drop_only=TRUE ! fakesink in gst_video_rate_transform_caps() function when caps size is 2 the for loop runs twice, first time the below code gets executed if (min_num != 0 || min_denom != 1) { s3 = gst_structure_copy (s); gst_structure_set (s3, "framerate", GST_TYPE_FRACTION, 0, 1, NULL); } and because of that if (s3 != NULL) ret = gst_caps_merge_structure (ret, s3); Now when loop runs the second time, s3 is not getting copied, but if (s3 != NULL) ret = gst_caps_merge_structure (ret, s3); hence it gives critical crash. when i initialize s3 to NULL in the for loop, the crash does not occur something like s1 = gst_structure_copy (s); s2 = gst_structure_copy (s); s3 = NULL; Can you please confirm if this is a proper fix, or is there any other way to fix the issue. Regards, Vineeth
Can you attach a patch so I can test it?
Created attachment 285241 [details] [review] proposed patch
Yes, that seems like the correct fix and in general it makes sense to set variables to NULL again after they became invalid. Will look closer later
Looked now ;) But will backport to 1.4 later commit 302f123c62275e04deec532f28c3983a7f054751 Author: Vineeth T M <vineeth.tm@samsung.com> Date: Wed Sep 3 15:23:26 2014 +0530 videorate: GstStructure refcount critical message s3 is not being initialized when run in a loop and the same was being freed, which resulted in the crash https://bugzilla.gnome.org/show_bug.cgi?id=735952
*** Bug 734271 has been marked as a duplicate of this bug. ***