| Summary: | [GStreamer] UI process crash during user media permission request calling gst_v4l2_open() in UI process | ||
|---|---|---|---|
| Product: | WebKit | Reporter: | Michael Catanzaro <mcatanzaro> |
| Component: | WebRTC | Assignee: | Nobody <webkit-unassigned> |
| Status: | NEW --- | ||
| Severity: | Normal | CC: | bugs-noreply, jan.brummer, mcatanzaro, pnormand, vjaquez, youennf |
| Priority: | P2 | ||
| Version: | WebKit Nightly Build | ||
| Hardware: | PC | ||
| OS: | Linux | ||
| See Also: |
https://bugs.webkit.org/show_bug.cgi?id=214811 https://bugs.webkit.org/show_bug.cgi?id=221333 |
||
|
Description
Michael Catanzaro
2020-07-26 13:42:22 PDT
OK, I have a reproducer for this one: visit my permanent BlueJeans meeting (link available privately on request) with webcam unplugged, then plug in the webcam. Crash is guaranteed. As far as I understand, the UIProcess request for the Media Capture permission, afterwards it queries for the available capture devices and which of them handle the constrains. In the case of GStreamer, querying the available capture devices requires the launch of gstreamer environment in the UIProcess and queries the Video4Linux devices available and their capabilities. If we want to move GStreamer/V4L2 operation out of UIProcess, we would need to add an IPC mechanism, iiuc, which I guess is what Mac does but with their platform API, not a WebKit IPC. In Source/WebKit/UIProcess/WebPageProxy.messages.in look for MEDIA_STREAM Hopefully when https://bugs.webkit.org/show_bug.cgi?id=209332 lands we can close this! The UI process still needs GStreamer though, for the can_show_mime_type public API. (In reply to Philippe Normand from comment #5) > Is this still happening as of r271396 ? For reasons I don't understand, -DENABLE_MEDIA_STREAM=ON causes *both* gtk-doc and gobject-introspection to crash. Both work fine if I use only -DENABLE_WEB_RTC=ON, but that alone doesn't seem to be enable to enable WebRTC. Needs further investigation. Ah I figured it out, there is a symbol conflict between boringssl and openssl:
(gdb) bt
#0 __pthread_rwlock_wrlock_full (abstime=0x0, clockid=0, rwlock=0x0) at pthread_rwlock_common.c:604
#1 __GI___pthread_rwlock_wrlock (rwlock=rwlock@entry=0x0) at pthread_rwlock_wrlock.c:27
#2 0x00007ffa4f842cd9 in CRYPTO_STATIC_MUTEX_lock_write (lock=lock@entry=0x0)
at ../../Source/ThirdParty/libwebrtc/Source/third_party/boringssl/src/crypto/thread_pthread.c:75
#3 0x00007ffa4f893236 in CRYPTO_get_ex_new_index (ex_data_class=ex_data_class@entry=0x0,
out_index=out_index@entry=0x0, argl=argl@entry=0, argp=argp@entry=0x0, free_func=free_func@entry=0x0)
at ../../Source/ThirdParty/libwebrtc/Source/third_party/boringssl/src/crypto/ex_data.c:146
#4 0x00007ffa46202b1b in ossl_get_ssl_conn_index () at ../../lib/vtls/openssl.c:353
#5 Curl_ossl_init () at ../../lib/vtls/openssl.c:1136
#6 0x00007ffa461a9c19 in Curl_ssl_init () at ../../lib/vtls/vtls.c:216
#7 Curl_ssl_init () at ../../lib/vtls/vtls.c:209
#8 global_init (flags=<optimized out>, memoryfuncs=<optimized out>) at ../../lib/easy.c:158
#9 0x00007ffa529df8ee in call_init (l=<optimized out>, argc=argc@entry=1, argv=argv@entry=0x7ffc951e9508,
env=env@entry=0x7ffc951e9518) at dl-init.c:74
#10 0x00007ffa529df9d8 in call_init (env=0x7ffc951e9518, argv=0x7ffc951e9508, argc=1, l=<optimized out>)
at dl-init.c:37
#11 _dl_init (main_map=0x7f9e60, argc=1, argv=0x7ffc951e9508, env=0x7ffc951e9518) at dl-init.c:121
#12 0x00007ffa4aa94095 in __GI__dl_catch_exception (exception=<optimized out>, operate=<optimized out>,
args=<optimized out>) at dl-error-skeleton.c:182
#13 0x00007ffa529e3e35 in dl_open_worker (a=0x7ffc951e91f0) at dl-open.c:783
#14 0x00007ffa4aa94038 in __GI__dl_catch_exception (exception=0x7ffc951e91d0,
operate=0x7ffa529e3a50 <dl_open_worker>, args=0x7ffc951e91f0) at dl-error-skeleton.c:208
#15 0x00007ffa529e366e in _dl_open (file=0x7ffc951e91d0 "", mode=-2147483647,
caller_dlopen=0x7ffa468cfdbb <__libdwfl_debuginfod_init+27>, nsid=-2, argc=1, argv=0x7ffc951e9508,
env=0x7ffc951e9518) at dl-open.c:864
#16 0x00007ffa475a339c in dlopen_doit (a=a@entry=0x7ffc951e9420) at dlopen.c:66
#17 0x00007ffa4aa94038 in __GI__dl_catch_exception (exception=exception@entry=0x7ffc951e93c0,
operate=0x7ffa475a3340 <dlopen_doit>, args=0x7ffc951e9420) at dl-error-skeleton.c:208
#18 0x00007ffa4aa94103 in __GI__dl_catch_error (objname=0x7eff60, errstring=0x7eff68, mallocedp=0x7eff58,
operate=<optimized out>, args=<optimized out>) at dl-error-skeleton.c:227
#19 0x00007ffa475a3bd9 in _dlerror_run (operate=0x7ffa475a3340 <dlopen_doit>, args=0x7ffc951e9420) at dlerror.c:170
#20 0x00007ffa475a3428 in __dlopen (file=<optimized out>, mode=<optimized out>) at dlopen.c:87
#21 0x00007ffa468cfdbb in __libdwfl_debuginfod_init () from /lib64/libdw.so.1
#22 0x00007ffa529df8ee in call_init (l=<optimized out>, argc=argc@entry=1, argv=argv@entry=0x7ffc951e9508,
env=env@entry=0x7ffc951e9518) at dl-init.c:74
#23 0x00007ffa529df9d8 in call_init (env=0x7ffc951e9518, argv=0x7ffc951e9508, argc=1, l=<optimized out>)
at dl-init.c:37
#24 _dl_init (main_map=0x7ffa529fc1a0, argc=1, argv=0x7ffc951e9508, env=0x7ffc951e9518) at dl-init.c:121
#25 0x00007ffa529d00ca in _dl_start_user () from /lib64/ld-linux-x86-64.so.2
#26 0x0000000000000001 in ?? ()
#27 0x00007ffc951eb058 in ?? ()
#28 0x0000000000000000 in ?? ()
Looks like an unintended consequence of debuginfod. Wow that's pretty wild. Looks like the dynamic linker now depends on curl and openssl? Wow.
(In reply to Michael Catanzaro from comment #7) > Looks like the dynamic linker now depends on curl and openssl? Wow. Well, elfutils certainly does, and it seems that gets initialized prior to main() by the dynamic linker. OK.... https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org/thread/FGGB7EZI7OGTLOJI45VNNX5LM6RQPKCD/ I failed to figure out what exactly pulls in libelf, but it certainly can no longer be combined with boringssl.... (In reply to Michael Catanzaro from comment #7) > Ah I figured it out, there is a symbol conflict between boringssl and > openssl: Fixed in bug #221333. With that fixed, I tested my reproducer for this issue again: (In reply to Michael Catanzaro from comment #1) > OK, I have a reproducer for this one: visit my permanent BlueJeans meeting > (link available privately on request) with webcam unplugged, then plug in > the webcam. Crash is guaranteed. However, this time the web process crashes even sooner: Video capture was requested but no device was found amongst 0 devices IntConstraint 1, min -1, max -1, exact -1, ideal 640 IntConstraint 2, min -1, max -1, exact -1, ideal 480 DoubleConstraint 4, min -1.000000, max -1.000000, exact -1.000000, ideal 30.000000 MediaConstraint 5 of type 4 malloc_consolidate(): unaligned fastbin chunk detected The last line looks bad. Looking at the backtrace, it's clearly memory corruption: (gdb) bt #0 0x00007f17f44169d5 in raise () from /lib64/libc.so.6 #1 0x00007f17f43ff8a4 in abort () from /lib64/libc.so.6 #2 0x00007f17f4458f27 in __libc_message () from /lib64/libc.so.6 #3 0x00007f17f4460c1c in malloc_printerr () from /lib64/libc.so.6 #4 0x00007f17f4461cc4 in malloc_consolidate () from /lib64/libc.so.6 #5 0x00007f17f4463b73 in _int_malloc () from /lib64/libc.so.6 #6 0x00007f17f44648f7 in malloc_check () from /lib64/libc.so.6 #7 0x00007f17f47af959 in operator new (sz=sz@entry=1024) at ../../../../libstdc++-v3/libsupc++/new_op.cc:50 #8 0x00007f17f81bef3f in __gnu_cxx::new_allocator<std::pair<char*, unsigned long> >::allocate (__n=<optimized out>, this=<optimized out>) at /usr/include/c++/10/ext/new_allocator.h:103 #9 std::allocator_traits<std::allocator<std::pair<char*, unsigned long> > >::allocate (__a=..., __n=<optimized out>) at /usr/include/c++/10/bits/alloc_traits.h:460 #10 std::_Vector_base<std::pair<char*, unsigned long>, std::allocator<std::pair<char*, unsigned long> > >::_M_allocate (__n=<optimized out>, this=<optimized out>) at /usr/include/c++/10/bits/stl_vector.h:346 #11 std::vector<std::pair<char*, unsigned long>, std::allocator<std::pair<char*, unsigned long> > >::_M_realloc_insert<std::pair<char*, unsigned long> > (this=this@entry=0x7f17e39ff9d8, __position= {first = 0x1a <error: Cannot access memory at address 0x1a>, second = 0}) at /usr/include/c++/10/bits/vector.tcc:440 #12 0x00007f17f81bb70e in std::vector<std::pair<char*, unsigned long>, std::allocator<std::pair<char*, unsigned long> > >::emplace_back<std::pair<char*, unsigned long> > (this=0x7f17e39ff9d8) at /usr/include/c++/10/bits/vector.tcc:121 #13 std::vector<std::pair<char*, unsigned long>, std::allocator<std::pair<char*, unsigned long> > >::push_back ( __x=..., this=0x7f17e39ff9d8) at /usr/include/c++/10/bits/stl_vector.h:1204 #14 bmalloc::BulkDecommit::add (this=0x7f17e39ff9c0, size=<optimized out>, ptr=<optimized out>, data=std::vector of length 32, capacity 32 = {...}) at ../../Source/bmalloc/bmalloc/BulkDecommit.h:61 #15 bmalloc::BulkDecommit::addLazy (size=<optimized out>, ptr=<optimized out>, this=0x7f17e39ff9c0) at ../../Source/bmalloc/bmalloc/BulkDecommit.h:43 #16 bmalloc::Heap::decommitLargeRange (this=this@entry=0x7f17f9633000, range=..., decommitter=...) at ../../Source/bmalloc/bmalloc/Heap.cpp:111 #17 0x00007f17f81bbf77 in bmalloc::Heap::scavenge (this=0x7f17f9633000, lock=..., decommitter=..., deferredDecommits=@0x7f17e39ff988: 4) at ../../Source/bmalloc/bmalloc/Heap.cpp:169 #18 0x00007f17f81c1529 in bmalloc::Scavenger::scavenge ( this=0x7f17f8538aa0 <bmalloc::StaticPerProcessStorageTraits<bmalloc::Scavenger>::Storage::s_memory>) at ../../Source/bmalloc/bmalloc/Scavenger.cpp:233 #19 bmalloc::Scavenger::scavenge ( this=0x7f17f8538aa0 <bmalloc::StaticPerProcessStorageTraits<bmalloc::Scavenger>::Storage::s_memory>) at ../../Source/bmalloc/bmalloc/Scavenger.cpp:205 #20 0x00007f17f81c18e9 in bmalloc::Scavenger::threadRunLoop ( this=0x7f17f8538aa0 <bmalloc::StaticPerProcessStorageTraits<bmalloc::Scavenger>::Storage::s_memory>) at ../../Source/bmalloc/bmalloc/Scavenger.cpp:500 #21 0x00007f17f81c1ce9 in bmalloc::Scavenger::threadEntryPoint (scavenger=<optimized out>) at ../../Source/bmalloc/bmalloc/Scavenger.cpp:395 #22 0x00007f17f47db5f4 in std::execute_native_thread_routine (__p=0xf533a0) at ../../../../../libstdc++-v3/src/c++11/thread.cc:80 #23 0x00007f17f49b63f9 in start_thread () from /lib64/libpthread.so.0 #24 0x00007f17f44da903 in clone () from /lib64/libc.so.6 I tried again with G_SLICE=always-malloc Malloc=1 and found something a bit nicer: #0 0x00007f19159999d5 in raise () from /lib64/libc.so.6 #1 0x00007f19159828a4 in abort () from /lib64/libc.so.6 #2 0x00007f19159dbf27 in __libc_message () from /lib64/libc.so.6 #3 0x00007f19159e3c1c in malloc_printerr () from /lib64/libc.so.6 #4 0x00007f19159e4cc4 in malloc_consolidate () from /lib64/libc.so.6 #5 0x00007f19159e6b73 in _int_malloc () from /lib64/libc.so.6 #6 0x00007f19159e78f7 in malloc_check () from /lib64/libc.so.6 #7 0x00007f1915fbabe6 in g_malloc (n_bytes=3991) at ../../../../Projects/glib/glib/gmem.c:106 #8 0x00007f1915fd5f3b in g_slice_alloc (mem_size=3991) at ../../../../Projects/glib/glib/gslice.c:1069 #9 0x00007f19151b870f in _sysmem_new_block (flags=0, maxsize=3847, align=7, offset=0, size=3840) at ../gst/gstallocator.c:413 #10 0x00007f19151c59ae in gst_buffer_new_allocate (allocator=0x0 [GstAllocator], size=3840, params=params@entry=0xa444878) at ../gst/gstbuffer.c:891 #11 0x00007f19153016bb in default_prepare_output_buffer (trans=0xa4448c0 [GstAudioConvert|audioconvert], inbuf=0x8c4d590 [GstBuffer], outbuf=0x7f185e32b7a0) at ../libs/gst/base/gstbasetransform.c:1704 #12 0x00007f1894523ddb in gst_audio_convert_prepare_output_buffer (base=0xa4448c0 [GstAudioConvert|audioconvert], inbuf=0x8c4d590 [GstBuffer], outbuf=0x7f185e32b7a0) at ../gst/audioconvert/gstaudioconvert.c:938 #13 0x00007f19153097d8 in default_generate_output (trans=0xa4448c0 [GstAudioConvert|audioconvert], outbuf=0x7f185e32b7a0) at ../libs/gst/base/gstbasetransform.c:2159 #14 0x00007f1915309f54 in gst_base_transform_chain (pad=<optimized out>, parent=0xa4448c0 [GstAudioConvert|audioconvert], buffer=0x7f185e32b7a0 [None]) at ../libs/gst/base/gstbasetransform.c:2341 #15 0x00007f19152038ad in gst_pad_chain_data_unchecked (pad=pad@entry=0xa444e00 [GstPad|sink], type=type@entry=4112, data=data@entry=0x8c4d590) at ../gst/gstpad.c:4399 #16 0x00007f1915206de9 in gst_pad_push_data (pad=pad@entry=0xa4443d0 [GstPad|src], type=type@entry=4112, data=data@entry=0x8c4d590) at ../gst/gstpad.c:4655 #17 0x00007f19152071fe in gst_pad_push (pad=0xa4443d0 [GstPad|src], buffer=buffer@entry=0x8c4d590 [GstBuffer]) at ../gst/gstpad.c:4774 #18 0x00007f18935a23eb in gst_queue_push_one (queue=0xa443940 [GstQueue|queue]) at ../plugins/elements/gstqueue.c:1386 #19 gst_queue_loop (pad=<optimized out>) at ../plugins/elements/gstqueue.c:1539 #20 0x00007f191522d487 in gst_task_func (task=0xa44af20 [GstTask|queue:src]) at ../gst/gsttask.c:328 #21 0x00007f1915fe5611 in g_thread_pool_thread_proxy (data=0x9fe9060) at ../../../../Projects/glib/glib/gthreadpool.c:354 #22 0x00007f1915fe4ee4 in g_thread_proxy (data=0xa44b000) at ../../../../Projects/glib/glib/gthread.c:826 #23 0x00007f1916016259 in linux_pthread_proxy (data=0xa44b000) at ../../../../Projects/glib/glib/gthread-posix.c:1259 #24 0x00007f1915f393f9 in start_thread () from /lib64/libpthread.so.0 #25 0x00007f1915a5d903 in clone () from /lib64/libc.so.6 There might be a problem in that code? But since it's memory corruption, that could be pointing to innocent unlucky code rather than the real source of the bug. I tried running the web process under valgrind: $ jhbuild run env WEB_PROCESS_CMD_PREFIX="valgrind --track-origins=yes" G_SLICE=always-malloc Malloc=1 WEBKIT_FORCE_SANDBOX=0 GIGACAGE_ENABLED=0 epiphany But it's so slow that I eventually gave up. |