-
Notifications
You must be signed in to change notification settings - Fork 240
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix kodi freeze by session close #729
Conversation
wvdecrypter/wvdecrypter.cpp
Outdated
@@ -1418,7 +1438,11 @@ class WVDecrypter : public SSD_DECRYPTER | |||
virtual void DestroySingleSampleDecrypter(AP4_CencSingleSampleDecrypter* decrypter) override | |||
{ | |||
if (decrypter) | |||
{ | |||
// close session before dispose | |||
decrypter->CloseSessionId(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can leave untouched libbento (Ap4CommonEncryption.h)
by removing virtual to CloseSessionId method,
and replace this with:
static_cast<WV_CencSingleSampleDecrypter*>(decrypter)->CloseSessionId();
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it's just because of base class. Will change it
Centralize and perform CloseSession call before dispose.
Block SetTimer while CloseSession is active to avoid endless loop.
Great work @Portisch, thanks for finding and fixing! |
@MisterD81 I'm about to test with Binge to confirm license renewal still works |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
|
…hile CloseSession is active to avoid endless loop. Sometimes when stopping a playback Kodi crashes with a following backtrace: (__m=<optimized out>, this=<optimized out>) at /usr/include/c++/12.1.0/bits/atomic_base.h:486 __b = <optimized out> at /usr/include/c++/12.1.0/atomic:87 (adp=std::shared_ptr<media::CdmAdapter> (use count 1, weak count 1) = {...}, delay=<optimized out>, context=<optimized out>) at /usr/src/debug/kodi-addon-inputstream-adaptive/inputstream.adaptive-20.3.3-Nexus/wvdecrypter/cdm/media/cdm/cdm_adapter.cc:81 at /usr/include/c++/12.1.0/bits/invoke.h:96, unsigned long long, void*), std::shared_ptr<media::CdmAdapter>, long long, void*> >::_M_invoke<0u, 1u, 2u, 3u>(std::_Index_tuple<0u, 1u, 2u, 3u>) (this=<optimized out>) at /usr/include/c++/12.1.0/bits/std_thread.h:252 at /usr/include/c++/12.1.0/bits/std_thread.h:259 at /usr/include/c++/12.1.0/bits/std_thread.h:210 at /usr/src/debug/gcc/libstdc++-v3/src/c++11/thread.cc:82 ret = <optimized out> pd = 0x85cf9080 unwind_buf = {cancel_jmp_buf = {{jmp_buf = {857629366, 66004830, -2049994624, -2008033272, -2008033282, 338, -2008033281, 8387456, -2058383360, -2049995908, 1920, 1080, 3840, 2160, 0, 10000000, -1431355392, 1107558643, 0 <repeats 46 times>}, mask_was_saved = 0}}, priv = {pad = {0x0, 0x0, 0x0, 0x0}, data = {prev = 0x0, cleanup = 0x0, canceltype = 0}}} not_first_call = <optimized out> robust = <optimized out> After searching in the github history it came out that there was a similar issue adressed in xbmc#728. For some reason that piece of code got removed in xbmc@8889fe9 (in pull request xbmc#883). The stack trace is from the Raspberry Pi 4 machine. But I can also reproduce the issue on my x86_64 Linux machine by adding a 1s sleep in the beginning of CdmAdapter::SetTimer. In order to reproduce it is necessary to quickly play/stop streams. Script attached at the end of the commit message can be used to ease the reproduction. In my environment running the script for 1-3 minutes makes Kodi crash. Although the root cause described in xbmc#729 was a busy loop. Right now address sanitizer reports: ``` AddressSanitizer:DEADLYSIGNAL ================================================================= ==108079==ERROR: AddressSanitizer: SEGV on unknown address 0x7f6e314f7d4a (pc 0x7f6e314f7d4a bp 0x7f6e263fd830 sp 0x7f6e263fd720 T464) ==108079==The signal is caused by a READ memory access. ==108079==Hint: PC is at a non-executable region. Maybe a wild jump? #0 0x7f6e314f7d4a (<unknown module>) xbmc#1 0x7f6e3151c066 (<unknown module>) xbmc#2 0x7f6e31526947 (<unknown module>) xbmc#3 0x7f6e31526729 (<unknown module>) xbmc#4 0x7f6e31526620 (<unknown module>) xbmc#5 0x7f6e315265a1 (<unknown module>) xbmc#6 0x7f6e31526585 (<unknown module>) xbmc#7 0x7f6e46ed72c2 in execute_native_thread_routine /usr/src/debug/gcc/gcc/libstdc++-v3/src/c++11/thread.cc:82 AddressSanitizer can not provide additional info. SUMMARY: AddressSanitizer: SEGV (<unknown module>) Thread T464 created by T51 here: #0 0x7f6e49464207 in __interceptor_pthread_create /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_interceptors.cpp:207 xbmc#1 0x7f6e46ed73a9 in __gthread_create /usr/src/debug/gcc/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/x86_64-pc-linux-gnu/bits/gthr-default.h:663 xbmc#2 0x7f6e46ed73a9 in std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) /usr/src/debug/gcc/gcc/libstdc++-v3/src/c++11/thread.cc:147 xbmc#3 0x7f6e31522028 (<unknown module>) xbmc#4 0x7f6e27569d40 (/home/dobo/.kodi/cdm/libwidevinecdm.so+0x969d40) xbmc#5 0x7f6e2757e7fc (/home/dobo/.kodi/cdm/libwidevinecdm.so+0x97e7fc) xbmc#6 0x7f6e27569c36 (/home/dobo/.kodi/cdm/libwidevinecdm.so+0x969c36) xbmc#7 0x7f6e3151fb28 (<unknown module>) xbmc#8 0x7f6e3151c0b1 (<unknown module>) xbmc#9 0x7f6e31526947 (<unknown module>) xbmc#10 0x7f6e31526729 (<unknown module>) xbmc#11 0x7f6e31526620 (<unknown module>) xbmc#12 0x7f6e315265a1 (<unknown module>) xbmc#13 0x7f6e31526585 (<unknown module>) xbmc#14 0x7f6e46ed72c2 in execute_native_thread_routine /usr/src/debug/gcc/gcc/libstdc++-v3/src/c++11/thread.cc:82 Thread T51 created by T45 here: #0 0x7f6e49464207 in __interceptor_pthread_create /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_interceptors.cpp:207 xbmc#1 0x7f6e46ed73a9 in __gthread_create /usr/src/debug/gcc/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/x86_64-pc-linux-gnu/bits/gthr-default.h:663 xbmc#2 0x7f6e46ed73a9 in std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) /usr/src/debug/gcc/gcc/libstdc++-v3/src/c++11/thread.cc:147 xbmc#3 0x7f6e31522028 (<unknown module>) xbmc#4 0x7f6e27569d40 (/home/dobo/.kodi/cdm/libwidevinecdm.so+0x969d40) xbmc#5 0x7f6e2757e7fc (/home/dobo/.kodi/cdm/libwidevinecdm.so+0x97e7fc) xbmc#6 0x7f6e2757e70e (/home/dobo/.kodi/cdm/libwidevinecdm.so+0x97e70e) xbmc#7 0x7f6e274e4ecc (/home/dobo/.kodi/cdm/libwidevinecdm.so+0x8e4ecc) xbmc#8 0x7f6e3151f280 (<unknown module>) xbmc#9 0x7f6e314e9ea1 (<unknown module>) xbmc#10 0x7f6e314e49bb (<unknown module>) xbmc#11 0x7f6e314f45ce (<unknown module>) xbmc#12 0x7f6e2889228f in SESSION::CSession::InitializeDRM(bool) /home/dobo/kodi/inputstream.adaptive/src/Session.cpp:643 xbmc#13 0x7f6e28893279 in SESSION::CSession::InitializePeriod(bool) /home/dobo/kodi/inputstream.adaptive/src/Session.cpp:723 xbmc#14 0x7f6e2888e36d in SESSION::CSession::Initialize() /home/dobo/kodi/inputstream.adaptive/src/Session.cpp:266 xbmc#15 0x7f6e28775f4c in CInputStreamAdaptive::Open(kodi::addon::InputstreamProperty const&) /home/dobo/kodi/inputstream.adaptive/src/main.cpp:101 xbmc#16 0x7f6e287871a1 in kodi::addon::CInstanceInputStream::ADDON_Open(AddonInstance_InputStream const*, INPUTSTREAM_PROPERTY*) (/usr/lib/kodi/addons/inputstream.adaptive/inputstream.adaptive.so.20.3.2+0x3871a1) xbmc#17 0x55c2811f4ddc in CInputStreamAddon::Open() (/usr/lib/kodi/kodi.bin+0xb66ddc) Thread T45 created by T0 here: #0 0x7f6e49464207 in __interceptor_pthread_create /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_interceptors.cpp:207 xbmc#1 0x7f6e46ed73a9 in __gthread_create /usr/src/debug/gcc/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/x86_64-pc-linux-gnu/bits/gthr-default.h:663 xbmc#2 0x7f6e46ed73a9 in std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) /usr/src/debug/gcc/gcc/libstdc++-v3/src/c++11/thread.cc:147 ``` The root cause of the crash is unknown as it comes directly from libwidevine library. But it crashes when we call cdm->TimerExpired when the session is closed. After applying mentioned commit I'm not able to reproduce the crash anymore. Script to reproduce the issue: ``` set -x URI='Change it to some uri to play' while true; do curl -s "http://kodi:kodi@127.0.0.1:8080/jsonrpc" -H 'Content-Type: application/json' --data "{\"jsonrpc\":\"2.0\",\"method\":\"Player.Open\",\"params\":{\"item\":{\"file\":\"$URI\"}}}" sleep $[ ($RANDOM % 70 + 30) / 10.0 ] curl -s "http://kodi:kodi@127.0.0.1:8080/jsonrpc" -H 'Content-Type: application/json' --data '{"jsonrpc":"2.0","method":"Player.Stop","params":{"playerid":1}}' sleep 1 done ```
Two points do cause Kodi to freeze randomly on session end:
exit_thread_flag
status tofalse
while being in CloseSession function cause waiting endless thattimer_thread_running
become falseMore than 150 start/stop cycles (30s cycle time) where successful done with this modification. Tested with CoreELEC 19.2-Matrix_nightly and last Amazon VOD. Before these changes Kodi got randomly frozen between 1-30 cycles.
This should solve issue #728