mpv-player / mpv

🎥 Command line video player
https://mpv.io
Other
28.18k stars 2.89k forks source link

Segfault in the `vo` thread with libmpv 0.38.0 #13929

Closed guihkx closed 6 months ago

guihkx commented 6 months ago

Important Information

Provide following Information:

Context

I'm the packager of RSS Guard (a news feed reader) on Flathub, which leverages libmpv to reproduce multimedia content.

Anyway, after testing RSS Guard with the recent 0.38.0 update, I began experiencing crashes.

After bisecting between versions 0.37.0 (good) and 0.38.0 (bad), I learned that commit 0e441525cfc2c0d56b6d4a5fc67016d7e29d1b2c was the first bad one.

I'm not really a C programmer, much less a graphics guy, so the reason for the crash is not immediately obvious to me, hence why I'm opening this issue. :)

Here's a gdb backtrace of the crash, against current master (4d80e7b72c0a4094f918779359fcce38eb796c40):

+backtrace full
#0  0x00007ffff5e7c429 in _gbm_device_destroy () at /usr/lib/x86_64-linux-gnu/libgbm.so.1
#1  0x00007ffff4f72388 in drm_egl_uninit (ctx=0x7fff98053780) at ../video/out/opengl/context_drm_egl.c:494
        p = 0x7fff98288ba0
        drm = <optimized out>
#2  0x00007ffff4f7252e in drm_egl_init (ctx=<optimized out>) at ../video/out/opengl/context_drm_egl.c:709
        p = <optimized out>
        drm = <optimized out>
        argb_format = <optimized out>
        xrgb_format = <optimized out>
        new_bo = <optimized out>
        rendernode_path = <optimized out>
        params = {check_visible = 0x73, swap_buffers = 0x7fff982b9d80, get_vsync = 0x7fff73dff310, external_swapchain = 0x7ffff52b030a <_int_free+714>}
#3  0x00007ffff4f10853 in create_in_contexts (vo=vo@entry=0x7fff5400d2b0, name=0x7ffff4f94483 "drm", api_auto=api_auto@entry=true, ctxs=ctxs@entry=0x7ffff5083880 <contexts>, size=size@entry=7, opts=...) at ../video/out/gpu/context.c:228
        ctx = 0x7fff98053780
        i = 3
#4  0x00007ffff4f10bb2 in ra_ctx_create (vo=vo@entry=0x7fff5400d2b0, opts=...) at ../video/out/gpu/context.c:268
        i = 3
        api_auto = true
        ctx_auto = <optimized out>
        old_probing = true
        ctx = 0x0
        done = <optimized out>
#5  0x00007ffff4f2e912 in preinit (vo=0x7fff5400d2b0) at ../video/out/vo_gpu.c:297
        p = 0x7fff540045f0
        ctx_opts = 0x7fff98040490
        __PRETTY_FUNCTION__ = "preinit"
#6  0x00007ffff4f2cc20 in vo_thread (ptr=0x7fff5400d2b0) at ../video/out/vo.c:1090
        vo = 0x7fff5400d2b0
        in = 0x7fff5400b950
        vo_paused = false
        r = <optimized out>
#7  0x00007ffff52a1e39 in start_thread () at /usr/lib/x86_64-linux-gnu/libc.so.6
#8  0x00007ffff53299c4 in clone () at /usr/lib/x86_64-linux-gnu/libc.so.6
+info registers
rax            0x0                 0
rbx            0x7fff98288ba0      140735746182048
rcx            0x7ffff53f3780      140737307948928
rdx            0x7fff980f69f0      140735744535024
rsi            0x1                 1
rdi            0x0                 0
rbp            0x7fff73dff1d0      0x7fff73dff1d0
rsp            0x7fff73dff1c0      0x7fff73dff1c0
r8             0x0                 0
r9             0x0                 0
r10            0x7ffff71fb59b      140737339438491
r11            0x246               582
r12            0x7fff98053780      140735743866752
r13            0x7fff982ac4d0      140735746327760
r14            0x7fff9803eb00      140735743781632
r15            0x7fff982b4fa0      140735746363296
rip            0x7ffff5e7c429      0x7ffff5e7c429 <_gbm_device_destroy+9>
eflags         0x10206             [ PF IF RF ]
cs             0x33                51
ss             0x2b                43
ds             0x0                 0
es             0x0                 0
fs             0x0                 0
gs             0x0                 0
fs_base        0x7fff73e006c0      140735137449664
gs_base        0x0                 0
+x/16i $pc
=> 0x7ffff5e7c429 <_gbm_device_destroy+9>:  mov    0x8(%rdi),%rbx
   0x7ffff5e7c42d <_gbm_device_destroy+13>: call   *0x20(%rdi)
   0x7ffff5e7c430 <_gbm_device_destroy+16>: test   %rbx,%rbx
   0x7ffff5e7c433 <_gbm_device_destroy+19>: je     0x7ffff5e7c460 <_gbm_device_destroy+64>
   0x7ffff5e7c435 <_gbm_device_destroy+21>: mov    0x10(%rbx),%rdi
   0x7ffff5e7c439 <_gbm_device_destroy+25>: test   %rdi,%rdi
   0x7ffff5e7c43c <_gbm_device_destroy+28>: je     0x7ffff5e7c460 <_gbm_device_destroy+64>
   0x7ffff5e7c43e <_gbm_device_destroy+30>: call   0x7ffff5e7c330 <dlclose@plt>
   0x7ffff5e7c443 <_gbm_device_destroy+35>: mov    (%rbx),%rdi
   0x7ffff5e7c446 <_gbm_device_destroy+38>: call   0x7ffff5e7c1f0 <free@plt>
   0x7ffff5e7c44b <_gbm_device_destroy+43>: mov    %rbx,%rdi
   0x7ffff5e7c44e <_gbm_device_destroy+46>: mov    -0x8(%rbp),%rbx
   0x7ffff5e7c452 <_gbm_device_destroy+50>: leave
   0x7ffff5e7c453 <_gbm_device_destroy+51>: jmp    0x7ffff5e7c1f0 <free@plt>
   0x7ffff5e7c458 <_gbm_device_destroy+56>: nopl   0x0(%rax,%rax,1)
   0x7ffff5e7c460 <_gbm_device_destroy+64>: mov    -0x8(%rbp),%rbx

Thank you in advance for any help.

guihkx commented 6 months ago

Here are most of the options RSS Guard passes to libmpv:

https://github.com/martinrotter/rssguard/blob/4.6.6/src/librssguard/gui/mediaplayer/libmpv/libmpvbackend.cpp#L53-L62

It's probably worth noting that my GPU driver doesn't really support GBM (as far as I understand), which seems to be related to the crash, given the backtrace information.

Dudemanguy commented 6 months ago

Does this work?

diff --git a/video/out/opengl/context_drm_egl.c b/video/out/opengl/context_drm_egl.c
index ce86570efe..da28093562 100644
--- a/video/out/opengl/context_drm_egl.c
+++ b/video/out/opengl/context_drm_egl.c
@@ -491,7 +491,8 @@ static void drm_egl_uninit(struct ra_ctx *ctx)
         if (p->gbm.surface)
             gbm_surface_destroy(p->gbm.surface);
         eglTerminate(p->egl.display);
-        gbm_device_destroy(p->gbm.device);
+        if (p->gbm.device)
+            gbm_device_destroy(p->gbm.device);

         if (p->drm_params.render_fd != -1)
             close(p->drm_params.render_fd);
guihkx commented 6 months ago

Yup, that did it! Thank you very much for the quick fix. :D

Dudemanguy commented 6 months ago

Another workaround would be explicitly setting vo to libmpv in RSS Guard but indeed we shouldn't be segfaulting during probing.

guihkx commented 6 months ago

Thanks for the heads up.

I may have to do that anyway, because with 0.38.0, playing any video causes a detached mpv window to pop up, instead of the old behavior where mpv would be embedded to RSS Guard's player (due to libmpv being the default back then, I suppose).

Additionally, I'm seeing another crash in a Qt-related thread after I play any video for the second time, which I'll have to investigate too (it's most likely unrelated to libmpv, though).

Thanks again.