debugging 如何在gst_object_unref()之后调试泄漏文件描述符的gstreamer管道?

lvjbypge  于 2023-03-23  发布在  其他
关注(0)|答案(1)|浏览(169)

我有一个自定义管道,在gstreamer速记中大致如下所示:

gst-launch-1.0 rtspsrc location=rtsp://<url-for-stream> ! rtph264depay ! h264parse ! imxvpudec ! *any-sink*
  • any-sink没关系,可以是fakesink,imxipusink,或者其他什么(我在imx 6平台上使用freescale imx插件)。我可以输出到任何我想要的sink,问题是一样的。

这种类型的管道在gst-launch-1.0中运行良好,因为它不需要正确地清理自己,但我需要在C++应用程序中使用直接GST API。这意味着我使用myPipeline = gst_pipeline_new("custom-pipeline"),然后按名称分配每个插件,链接它们,并运行管道。稍后我需要停止管道并调用gst_object_unref(myPipeline)。在执行此操作时,我观察到文件描述符被留下。我稍后需要重新启动管道,因此泄漏是复合的。这需要经常发生,以至于泄漏的描述符给予我一个异常:
GLib-ERROR **: Creating pipes for GWakeup: Too many open files
我可以用lsof分析打开的文件...

lsof +E -aUc myGstApplication        
lsof: netlink UNIX socket msg peer info error
COMMAND    PID USER   FD   TYPE     DEVICE SIZE/OFF     NODE NAME
myGstApplication 5943 root    3u  unix 0xabfb6c00      0t0 11200335 type=STREAM
myGstApplication 5943 root   11u  unix 0xd9d47180      0t0 11207020 type=STREAM

。。。更多,取决于它运行的时间。。

myGstApplication 5943 root   50u  unix 0xabe99080      0t0 11211987 type=STREAM

每次unref()和重新构建管道时,我似乎得到了两个新的'type=STREAM'文件描述符。
在lsof中查看描述符是很好的,但我不知道如何跟踪这些文件在代码中的来源。例如,lsof的输出是否真的能引导我获得更好的调试信息?如何跟踪这些泄漏的真正来源并阻止它们?有更好的方法...对吗?
我怀疑rtspsrc gstreamer pipeline元素与此有关,但rtspsrc本身就是底层gstreamer实现的一个泥潭。(udpsrcs,demuxers,etc,etc.)我不相信这是rtspsrc中的bug,因为很多其他人似乎都在使用这一个而没有复制同样的东西。我是否可以在我的应用程序代码中做一些事情,从而在非明显的方式?
任何帮助是非常感谢,谢谢!

6ju8rftf

6ju8rftf1#

好研究&有趣的问题!
根据lsof输出,泄漏的文件描述符似乎源自socketpair syscalls。您可以使用strace确认这一点:
strace -fe socketpair myGstApplication
在此之后,您可以省略对socketpair sycall的过滤,并查看完整的strace输出,试图了解这些FD的用途。我用gst-launch-1.0尝试了这一点,结果不确定。这些FD似乎在两端都被设置为只读,并且没有任何东西被传输......因此它们必须仅用于同一应用程序的多个线程/子进程之间的控制/协调。
下一个尝试是gdb:
gdb -ex 'break socketpair' -ex run myGstApplication
当它在断点处停止时,使用 bt 命令查看堆栈跟踪。可能安装gstreamer的debug包是一个好主意,可以获得更多可读的堆栈跟踪。
HTH:)

相关问题