dougg3 / obs-ios-camera-source

Use your iPhone camera as a video source in OBS Studio and stream high quality video from your iPhone's camera over USB
https://obs.camera/
GNU General Public License v2.0
49 stars 18 forks source link

obs segfault #4

Closed rrondeau closed 3 years ago

rrondeau commented 3 years ago

Hi

First, many thanks for this, using the plugin for more than 6 months without a hitch.

Since monday my obs studio crash when lauching with my iphone plugged in. I am using fedora 33 with obs-studio from rpm-fusion.

I get a segfault with libsamba :

obs[19525]: segfault at 34 ip 00007f29b5677f20 sp 00007ffc5f78c250 error 4 in libsamba-sockets-samba4.so[7f29b566a000+18000]

Part of the stack trace :

Stack trace of thread 19525:
#0  0x00007f29b5677f20 socket_send (libsamba-sockets-samba4.so + 0xdf20) 
#1  0x00007f28ef18f034 n/a (/home/rrondeau/.config/obs-studio/plugins/obs-ios-camera-source/bin/64bit/obs-ios-camera-source.so + 0x4b034)
#2  0x00007f28ef18f19e n/a (/home/rrondeau/.config/obs-studio/plugins/obs-ios-camera-source/bin/64bit/obs-ios-camera-source.so + 0x4b19e)
#3  0x00007f28ef18f413 n/a (/home/rrondeau/.config/obs-studio/plugins/obs-ios-camera-source/bin/64bit/obs-ios-camera-source.so + 0x4b413)
#4  0x00007f28ef19025f n/a (/home/rrondeau/.config/obs-studio/plugins/obs-ios-camera-source/bin/64bit/obs-ios-camera-source.so + 0x4c25f)
#5  0x00007f28ef1894d9 n/a (/home/rrondeau/.config/obs-studio/plugins/obs-ios-camera-source/bin/64bit/obs-ios-camera-source.so + 0x454d9)
#6  0x00007f28ef18957c n/a (/home/rrondeau/.config/obs-studio/plugins/obs-ios-camera-source/bin/64bit/obs-ios-camera-source.so + 0x4557c)
#7  0x00007f28ef1891d3 n/a (/home/rrondeau/.config/obs-studio/plugins/obs-ios-camera-source/bin/64bit/obs-ios-camera-source.so + 0x451d3)
#8  0x00007f28ef17e003 n/a (/home/rrondeau/.config/obs-studio/plugins/obs-ios-camera-source/bin/64bit/obs-ios-camera-source.so + 0x3a003)
#9  0x00007f28ef17d308 n/a (/home/rrondeau/.config/obs-studio/plugins/obs-ios-camera-source/bin/64bit/obs-ios-camera-source.so + 0x39308)
#10 0x00007f29bdedc0b7 obs_source_create_internal (libobs.so.0 + 0x650b7)
#11 0x00007f29bdefce31 obs_load_source_type (libobs.so.0 + 0x85e31)
#12 0x00007f29bdefd252 obs_load_sources (libobs.so.0 + 0x86252)
#13 0x0000557f6f5ba084 _ZN8OBSBasic4LoadEPKc (obs + 0xac084)
#14 0x0000557f6f5c1c49 _ZN8OBSBasic7OBSInitEv (obs + 0xb3c49)
#15 0x0000557f6f5888e4 main (obs + 0x7a8e4)
#16 0x00007f29bcdfe1e2 __libc_start_main (libc.so.6 + 0x281e2)
#17 0x0000557f6f58a0ae _start (obs + 0x7c0a

I tried to downgrade obs-studio from 26.1.0 to 26.0.2. I tried to downgrade samba-client from 4.13.3 to 4.13.0

No luck

Any idea how to fix this ?

dougg3 commented 3 years ago

Hey @rrondeau ,

I don't know much about Fedora, but I struggled my way through setting up a VM with OBS and FFmpeg and compiling the plugin, and it looks like I am indeed able to replicate this issue. The stack trace I get is a bit more detailed, and much longer, but the interesting part is at the top:

#0  0x00007fffed77cf20 in socket_send () from /usr/lib64/samba/libsamba-sockets-samba4.so
#1  0x00007fffa956913c in send_packet () from /home/fedora/.config/obs-studio/plugins/obs-ios-camera-source/bin/64bit/obs-ios-camera-source.so
#2  0x00007fffa95692a6 in send_plist_packet () from /home/fedora/.config/obs-studio/plugins/obs-ios-camera-source/bin/64bit/obs-ios-camera-source.so
#3  0x00007fffa956951b in send_list_devices_packet () from /home/fedora/.config/obs-studio/plugins/obs-ios-camera-source/bin/64bit/obs-ios-camera-source.so
#4  0x00007fffa956a367 in usbmuxd_get_device_list () from /home/fedora/.config/obs-studio/plugins/obs-ios-camera-source/bin/64bit/obs-ios-camera-source.so
#5  0x00007fffa95635e1 in portal::Portal::addConnectedDevices() () from /home/fedora/.config/obs-studio/plugins/obs-ios-camera-source/bin/64bit/obs-ios-camera-source.so
#6  0x00007fffa9563684 in portal::Portal::reloadDeviceList() () from /home/fedora/.config/obs-studio/plugins/obs-ios-camera-source/bin/64bit/obs-ios-camera-source.so
#7  0x00007fffa95632db in portal::Portal::Portal(portal::PortalDelegate*) () from /home/fedora/.config/obs-studio/plugins/obs-ios-camera-source/bin/64bit/obs-ios-camera-source.so
#8  0x00007fffa9558053 in IOSCameraInput::IOSCameraInput(obs_source*, obs_data*) () from /home/fedora/.config/obs-studio/plugins/obs-ios-camera-source/bin/64bit/obs-ios-camera-source.so
#9  0x00007fffa9557358 in CreateIOSCameraInput(obs_data*, obs_source*) () from /home/fedora/.config/obs-studio/plugins/obs-ios-camera-source/bin/64bit/obs-ios-camera-source.so
#10 0x00007ffff5eb834a in obs_source_create_internal () from /lib64/libobs.so.0

I will try to track down what's happening. This stack trace may help us understand why it's failing. It sure sounds like some kind of update broke it.

rrondeau commented 3 years ago

I tried to run obs and the plugin with gdb. I got this :

#0  0x00007fffee7abc64 in socket_send () at /usr/lib64/samba/libsamba-sockets-samba4.so
#1  0x00007fff88b7813c in send_packet (sfd=50, message=8, tag=1, payload=0x1b22e60, payload_size=488) at /home/rrondeau/git/perso/obs-ios-camera-source/deps/libusbmuxd/src/libusbmuxd.c:400
#2  0x00007fff88b782a6 in send_plist_packet (sfd=50, tag=1, message=0x1ae53e0) at /home/rrondeau/git/perso/obs-ios-camera-source/deps/libusbmuxd/src/libusbmuxd.c:431
#3  0x00007fff88b7851b in send_list_devices_packet (sfd=50, tag=1) at /home/rrondeau/git/perso/obs-ios-camera-source/deps/libusbmuxd/src/libusbmuxd.c:499
#4  0x00007fff88b79367 in usbmuxd_get_device_list (device_list=0x7fffffffc740) at /home/rrondeau/git/perso/obs-ios-camera-source/deps/libusbmuxd/src/libusbmuxd.c:938
#5  0x00007fff88b725e1 in portal::Portal::addConnectedDevices() (this=0x1909378) at /home/rrondeau/git/perso/obs-ios-camera-source/deps/portal/src/Portal.cpp:109
#6  0x00007fff88b72684 in portal::Portal::reloadDeviceList() (this=0x1909378) at /home/rrondeau/git/perso/obs-ios-camera-source/deps/portal/src/Portal.cpp:126
#7  0x00007fff88b722db in portal::Portal::Portal(portal::PortalDelegate*) (this=0x1909378, delegate=0x1909240) at /home/rrondeau/git/perso/obs-ios-camera-source/deps/portal/src/Portal.cpp:57
#8  0x00007fff88b67053 in IOSCameraInput::IOSCameraInput(obs_source*, obs_data*) (this=0x1909240, source_=0x1aee000, settings=0x19210a0)
    at /home/rrondeau/git/perso/obs-ios-camera-source/src/obs-ios-camera-source.cpp:74
#9  0x00007fff88b66358 in CreateIOSCameraInput(obs_data_t*, obs_source_t*) (settings=0x19210a0, source=0x1aee000) at /home/rrondeau/git/perso/obs-ios-camera-source/src/obs-ios-camera-source.cpp:371
#10 0x00007ffff6259c2a in obs_source_create_internal () at /lib64/libobs.so.0
#11 0x00007ffff626bb81 in obs_load_source_type () at /lib64/libobs.so.0
#12 0x00007ffff626e3c2 in obs_load_sources () at /lib64/libobs.so.0
#13 0x000000000049e750 in OBSBasic::Load(char const*) (this=0xa370b0, file=0x7fffffffd040 "/home/rrondeau/.config/obs-studio/basic/scenes/Untitled.json")
    at /home/rrondeau/git/perso/obs-studio/UI/window-basic-main.cpp:973
#14 0x00000000004a2976 in OBSBasic::OBSInit() (this=0xa370b0) at /home/rrondeau/git/perso/obs-studio/UI/window-basic-main.cpp:1783
#15 0x000000000047feff in OBSApp::OBSInit() (this=0x7fffffffd690) at /home/rrondeau/git/perso/obs-studio/UI/obs-app.cpp:1415
#16 0x0000000000482503 in run_program(std::fstream&, int, char**) (logFile=..., argc=1, argv=0x7fffffffdd68) at /home/rrondeau/git/perso/obs-studio/UI/obs-app.cpp:2052
#17 0x0000000000484203 in main(int, char**) (argc=1, argv=0x7fffffffdd68) at /home/rrondeau/git/perso/obs-studio/UI/obs-app.cpp:2697

i will try to poke around but last time i read/wrote c/c++ was like ten years ago :)

rrondeau commented 3 years ago

Ok so i just realize wtf is libsamba doing in a obs/usb connection. I renamed socket_send in the libusbmuxd sources and everything is working again !

dougg3 commented 3 years ago

Nice job! That thought crossed my mind too but I assumed it was just using samba’s socket functionality for some strange reason, haha. I’m glad you figured it out...now we need to decide how to fix it permanently because it’s likely that this will affect other people as time goes on. I guess since this project has a bundled copy of libusbmuxd we could just do exactly what you did on the bundled library source. Want to send a pull request?

I wonder why libsamba is even available at that point in time...maybe it’s used by OBS somewhere else. I wonder if some of the other distros are going to run into this problem as time goes on and packages get updated.

rrondeau commented 3 years ago

libsamba is available because its installed by default on fedora as a dependency of gnome-shell. I dont know how to fix this properly because i dont know how to tell the plugin to avoid using shared libraries installed on my computer.

If you know how to fix this, i will be happy to test anything :)

dougg3 commented 3 years ago

My first instinct is to expect other distros to also have the same problem given how common gnome-shell is. I did some research and I think I know what's going on. First of all, ldd confirms that libsamba-sockets-samba4.so is definitely a dependency of something that the plugin is linking against:

[fedora@fedora33 build]$ ldd obs-ios-camera-source.so 
    linux-vdso.so.1 (0x00007fffa599a000)
    libobs.so.0 => /lib64/libobs.so.0 (0x00007f0a3f688000)
    libavcodec.so.58 => /lib64/libavcodec.so.58 (0x00007f0a3e2db000)
    libavutil.so.56 => /lib64/libavutil.so.56 (0x00007f0a3e036000)
...
    libsamba-sockets-samba4.so => /usr/lib64/samba/libsamba-sockets-samba4.so (0x00007fd6af4b7000)
...

But it's not a direct dependency, so one of its direct dependencies is pulling it in instead:

[fedora@fedora33 build]$ readelf -d obs-ios-camera-source.so | grep NEEDED
 0x0000000000000001 (NEEDED)             Shared library: [libobs.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libavcodec.so.58]
 0x0000000000000001 (NEEDED)             Shared library: [libavutil.so.56]
 0x0000000000000001 (NEEDED)             Shared library: [libobs-frontend-api.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libstdc++.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libm.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libgcc_s.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libpthread.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]

With some trial and error running the same commands (ldd showing all dependencies including dependencies of dependencies, readelf only showing direct dependencies), I can walk the dependency tree and figure out how it's actually being added:

libobs -> libavformat -> libsmbclient (and then from this point on several of libsmbclient's samba dependencies use it).

If we look at libavformat's source code, it does indeed have optional libsmbclient support. Ubuntu 20.04 doesn't seem to have it compiled in, because ldd doesn't show its version of libavformat depending on libsmbclient, but Fedora 33 does.

I did some more digging, and I found the commit on RPM Fusion's mailing list where SMB support was enabled. This was committed on December 31, 2020. This explains why this problem recently started for you.

Anybody who uses FFmpeg with SMB support enabled could also be running into this issue because with SMB support enabled, you end up being indirectly linked with libsamba-sockets-samba4.so, and thus end up with a conflict where you're dynamically linked against a library that provides a function called socket_send.

Basically this situation is unfortunate -- we're pulling in a ton of dependencies without realizing it, and one of the dependencies is exporting a quite generically named function that happens to have a symbol name conflict with another one of our dependencies that we happen to be compiling as a static library instead of a shared library (but whether it's static or not doesn't seem to matter).

I think the best line of attack here, because libusbmuxd is something we have control over and Samba isn't, is to rename the socket* functions to have a "usbmuxd" prefix or something along those lines. There might be some clever linker trick to avoid the conflict too, but I think renaming the usbmuxd functions will be easier to understand for everyone involved and less error-prone. I'll work on an update. We might want to request Samba to rename their functions too because socket_send is a super generic name for a library to be exporting and other people might run into this same issue...but I don't know what kind of logistics would be involved in that.

rrondeau commented 3 years ago

Thx for the digging and the explanation !!! I can make a PR to rename the basic function of the embedded libusbmuxd if you want !

dougg3 commented 3 years ago

That would be great if you don't mind! I think as part of the fix, we should rename all of the socket_* functions in the embedded libusbmuxd because this conflict could happen again in the future with a different function name. Plus it will look better for function naming consistency.