-
Notifications
You must be signed in to change notification settings - Fork 238
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
[AdaptiveTree] Lock live segments in start_stream() #1121
Conversation
Sometimes I'm encountering a crash when starting a live dash stream with a following backtrace: #0 0x910819d4 in adaptive::AdaptiveStream::start_stream() (this=<optimized out>) at /usr/src/debug/kodi-addon-inputstream-adaptive/inputstream.adaptive-20.3.2-Nexus/src/common/AdaptiveStream.cpp:606 xbmc#1 0x91069d0c in CInputStreamAdaptive::OpenStream(int) (this=0xaf51fa68, streamid=1006) at /usr/src/debug/kodi-addon-inputstream-adaptive/inputstream.adaptive-20.3.2-Nexus/src/main.cpp:309 xbmc#2 0x00e2f5d4 in CDVDDemuxClient::OpenStream(int) () xbmc#3 0x00e97ad4 in CVideoPlayer::OpenStream(CCurrentStream&, long long, int, int, bool) () xbmc#4 0x00e9e3c8 in CVideoPlayer::OpenDefaultStreams(bool) () xbmc#5 0x00ea3b18 in CVideoPlayer::Prepare() () xbmc#6 0x00ea5dc0 in CVideoPlayer::Process() () xbmc#7 0x011dcc6c in CThread::Action() () AdaptiveStream.cpp:606 points to a following line: ``` currentPTSOffset_ = (next_segment->startPTS_ * current_rep_->timescale_ext_) / current_rep_->timescale_int_; ``` After taking a look on the assembly listing: (gdb) disas /m _ZN8adaptive14AdaptiveStream12start_streamEv ... 0x910819c8 <+1592>: ldrne r3, [sp, xbmc#28] 0x910819d0 <+1600>: ldr r4, [r3, xbmc#324] ; 0x144 => 0x910819d4 <+1604>: ldr r0, [r8, xbmc#40] ; 0x28 0x910819d8 <+1608>: ldr r12, [r8, xbmc#44] ; 0x2c 0x910819dc <+1612>: mov r8, #0 0x910819e4 <+1620>: mov r3, r8 0x910819e8 <+1624>: umull r0, r1, r0, r4 0x910819ec <+1628>: mov r2, r9 0x910819f0 <+1632>: mla r1, r4, r12, r1 0x910819f4 <+1636>: bl 0x9105a6b4 <__aeabi_uldivmod@plt> ... it appears that $r3 contains a valid representation: (gdb) p *((AdaptiveTree::Representation*) $r3) $1 = {url_ = "http://lb2-e2-18.pluscdn.pl/ch/1456330/123/dash/294f032c/1080p/p_3f26ad64-5258-452e-9bdc-209c361003e9_1667995241000/init.mp4", id = "1080p", codecs_ = "avc1.640028", codec_private_data_ = "", source_url_ = "", base_url_ = "http://lb2-e2-18.pluscdn.pl/ch/1456330/123/dash/294f032c/", bandwidth_ = 5000000, samplingRate_ = 0, width_ = 1920, height_ = 1080, fpsRate_ = 25, fpsScale_ = 1, aspect_ = 0, assured_buffer_duration_ = 20, max_buffer_duration_ = 40, static BYTERANGE = 0, static INDEXRANGEEXACT = 1, static TEMPLATE = 2, static TIMELINE = 4, static INITIALIZATION = 8, static SEGMENTBASE = 16, static SUBTITLESTREAM = 32, static INCLUDEDSTREAM = 64, static URLSEGMENTS = 128, static ENABLED = 256, static WAITFORSEGMENT = 512, static INITIALIZATION_PREFIXED = 1024, static DOWNLOADED = 2048, static INITIALIZED = 4096, flags_ = 14, hdcpVersion_ = 0, indexRangeMin_ = 0, indexRangeMax_ = 0, channelCount_ = 0 '\000', nalLengthSize_ = 0 '\000', pssh_set_ = 2, expired_segments_ = 0, containerType_ = adaptive::AdaptiveTree::CONTAINERTYPE_MP4, segtpl_ = { initialization = "http://lb2-e2-18.pluscdn.pl/ch/1456330/123/dash/294f032c/1080p/p_3f26ad64-5258-452e-9bdc-209c361003e9_1667995241000/init.mp4", media = "http://lb2-e2-18.pluscdn.pl/ch/1456330/123/dash/294f032c/$RepresentationID$/p_3f26ad64-5258-452e-9bdc-209c361003e9_1667995241000/t$Time$.mp4", media_url = "http://lb2-e2-18.pluscdn.pl/ch/1456330/123/dash/294f032c/1080p/p_3f26ad64-5258-452e-9bdc-209c361003e9_1667995241000/t$Time$.mp4", timescale = 90000, duration = 230395}, startNumber_ = 4, nextPts_ = 20170141682400, ptsOffset_ = 0, duration_ = 972288000, timescale_ = 90000, timescale_ext_ = 100, timescale_int_ = 9, initialization_ = {range_begin_ = 0, range_end_ = 18446744073709551615, url = "", startPTS_ = 0, m_duration = 0, pssh_set_ = 0}, segments_ = {basePos = 0, data = std::vector of length 4220, capacity 4220 = {{ range_begin_ = 20169170085600, range_end_ = 1, url = "", startPTS_ = 20169170085600, m_duration = 0, pssh_set_ = 0}, {range_begin_ = 20169170316000, range_end_ = 2, url = "", startPTS_ = 20169170316000, m_duration = 0, pssh_set_ = 0}, {range_begin_ = 20169170546400, range_end_ = 3, url = "", startPTS_ = 20169170546400, m_duration = 0, pssh_set_ = 0}, { range_begin_ = 20169170776800, range_end_ = 4, url = "", startPTS_ = 20169170776800, m_duration = 0, pssh_set_ = 0}, {range_begin_ = 20169171007200, range_end_ = 5, url = "", startPTS_ = 20169171007200, m_duration = 0, pssh_set_ = 0}, {range_begin_ = 20169171237600, range_end_ = 6, url = "", startPTS_ = 20169171237600, m_duration = 0, pssh_set_ = 0}, { range_begin_ = 20169171468000, range_end_ = 7, url = "", startPTS_ = 20169171468000, m_duration = 0, pssh_set_ = 0}, {range_begin_ = 20169171698400, range_end_ = 8, url = "", ... $r8 should point to a valid next segment but doesn't: (gdb) p *((adaptive::AdaptiveTree::Segment*) $r8) Cannot access memory at address 0xa1a7dd88 After manually calculating next segment position in gdb it should point to: (gdb) p ((AdaptiveTree::Representation*) $r3)->current_segment_ - &((AdaptiveTree::Representation*) $r3)->segments_.data[0] + 1 $2 = 4211 (gdb) p &((AdaptiveTree::Representation*) $r3)->segments_.data[4211] $3 = (adaptive::AdaptiveTree::Segment *) 0x97ae9f10 (gdb) p ((AdaptiveTree::Representation*) $r3)->segments_.data[4211] $4 = {range_begin_ = 20170140300000, range_end_ = 4212, url = "", startPTS_ = 20170140300000, m_duration = 0, pssh_set_ = 0} My conclusion is that we are properly calculating next segment position but for some reason the memory got deallocated. My assumption is that updater thread has managed to parse the dash xml and update the segments.
when there is a problem and you are not sure what you are doing,
PR are not for discussions for problems, uncomplete investigations, or so so please follow these simple contribution rules |
@CastagnaIT I've converted it to a draft. Do you want me to open an issue to move the discussion? |
Hi @dobo90 |
Actually this is ready for the review. I was able to reproduce on my x86 machine by forcing update interval to 1 second and adding sleep inside start_stream(). This is the commit which does that dobo90@3243687. Beware that it also enables compilation with address sanitizer (it will work only on Linux machines). After compiling from specified commit, starting a live dash stream it will produce following error in address sanitizer.
I've added also logs which indicate that update had happened during start_stream() and it invalidated segments.
Applying commit in that PR fixes the issue (segement update won't happen during start_stream). |
I see that you do not intend to follow our rules |
Sometimes I'm encountering a crash when starting a live dash stream with a following backtrace:
AdaptiveStream.cpp:606 points to a following line:
After taking a look on the assembly listing:
it appears that $r3 contains a valid representation:
$r8 should point to a valid next segment but doesn't:
After manually calculating next segment position in gdb it should point to:
My conclusion is that we are properly calculating next segment position but for some reason the memory got deallocated. My assumption is that updater thread has managed to parse the dash xml and update the segments.
I haven't tested it heavily. Can someone confirm whether it's possible that dash updater has corrupted memory when starting a stream?