DVD navigation improvement (use of Prev / Next in menu structures when appropriate) -- Trac #9674 work #9

Closed
wants to merge 1 commit into
from

Conversation

Projects
None yet
2 participants
Member

Voyager1 commented Jan 10, 2011

This is a patch for the use of Prev/Next in DVD menu structures especially in DVDs where the "trailers" are part of the menu structure. Currently the Prev/Next function does not work, and brings you straight back to the xbmc menu. The reason is that the action doesn't get handled so it's delegated to the GUI.

There are DVD's where it can be quite annoying that you have to wait several minutes (sometimes 10 mins or so), before you can get to the DVD root menu. It does not happen that frequently, but I have two cases of DVDs where trailers are part of the menu.

See reopened Trac ticket 9674.

Note: the code comments in DVDPlayer.cpp stating "// needs the modified CDVDInputStreamNavigator::SeekChapter(int iChapter) method, assuming dvdnav_..." are only relevant when this DVD playback, but the code itself is -of course- generally applicable.

Member

Voyager1 commented Jan 25, 2011

who's currently responsible for the dvdplayer code? (haven't seen elupus contributing lately).

Member

elupus commented Feb 6, 2011

Still me, just been on vacation

Member

elupus commented Feb 6, 2011

Still me, just been on vacation.
Looked again on your code.. ACTION_PREV/NEXT_ITEM was already disabled to do what you want once before. To allow dvd stacks. So that can't be in the change (page up/down is fine). Secondly i don't like the miss-use of seekchapter. inputstream::seekchapter should never allow stuff outside of chapter numbers.

dvdplayer.cpp should instead if a chapter request lies outside of chapter border request OnNext()/OnPrev().

Member

Voyager1 commented Feb 6, 2011

hello elupus - I have updated the commit according to your input.

  1. No longer misusing seekchapter
  2. When in Menu, since dvdplayer doesn't really know the real program chain id, we call OnPrevious/OnNext instead. This is safe with regard to the dvd stacks since we're in menu structure ONLY.
Member

elupus commented Feb 7, 2011

That diff looks fine. Will commit when i have the time.

Member

Voyager1 commented Feb 14, 2011

great, thanks!

@ghost

ghost commented Feb 16, 2011

okay to close this i assume?

Member

Voyager1 commented Feb 17, 2011

I think so, commit was accepted by elupus

@Red-F Red-F referenced this pull request in Red-F/xbmc Jun 13, 2011

@margro margro Merge pull request #9 from 'red-f/master' 3295289

@garbear garbear referenced this pull request in garbear/xbmc Aug 12, 2013

@opdenkamp opdenkamp Merge pull request #9 from garbear/dialogok2
OK Dialog for add-ons (take 2)
76a8c07

@koying koying added a commit to koying/xbmc that referenced this pull request Feb 24, 2014

@koying @wolfgar koying + wolfgar Merge pull request #9
FIX: [imx] runtime vivante egl extensions
b3dda97

@koying koying added a commit to koying/xbmc that referenced this pull request Mar 6, 2014

@koying koying Merge pull request #9
FIX: [imx] runtime vivante egl extensions
194f624

@koying koying added a commit to koying/xbmc that referenced this pull request Mar 12, 2014

@koying koying Merge pull request #9
FIX: [imx] runtime vivante egl extensions
4fb8cff

@koying koying added a commit to koying/xbmc that referenced this pull request May 5, 2014

@koying koying Merge pull request #9
FIX: [imx] runtime vivante egl extensions
f915dc1

@koying koying added a commit to koying/xbmc that referenced this pull request May 20, 2014

@koying koying Merge pull request #9
FIX: [imx] runtime vivante egl extensions
e8e4be0

@koying koying added a commit to koying/xbmc that referenced this pull request Jun 1, 2014

@koying koying Merge pull request #9
FIX: [imx] runtime vivante egl extensions
d8198b5

@janbar janbar added a commit to janbar/xbmc that referenced this pull request Jul 3, 2015

@janbar janbar Do not run thumb extractor job on PVR recording item
Fix/workaround for crash when opening PVR recording for playback. Seems thumb extractor job close pvr recorded stream while read operation is running. Now as workaround this commit forbids the thumb extractor job for PVR item.

Program terminated with signal SIGSEGV, Segmentation fault.
Thread 1 (Thread 0x7fededd6a700 (LWP 5095)):
...
#4  0x0000000000fda1af in PVR::CPVRClient::ReadStream (this=0x7fedcc000c40, lpBuf=lpBuf@entry=0x7fede40bdf80, uiBufSize=uiBufSize@entry=32768) at PVRClient.cpp:1302
#5  0x0000000000fe462c in PVR::CPVRClients::ReadStream (this=<optimized out>, lpBuf=lpBuf@entry=0x7fede40bdf80, uiBufSize=uiBufSize@entry=32768) at PVRClients.cpp:1551
#6  0x0000000000af4a86 in XFILE::CPVRFile::Read (this=<optimized out>, buffer=0x7fede40bdf80, size=32768) at PVRFile.cpp:117
#7  0x000000000095ddc9 in CDVDInputStreamPVRManager::Read (this=0x7fede4027b50, buf=<optimized out>, buf_size=<optimized out>) at DVDInputStreamPVRManager.cpp:177
#8  0x0000000001724d92 in fill_buffer (s=0x7fede4059a60) at libavformat/aviobuf.c:477
#9  avio_read (s=s@entry=0x7fede4059a60, buf=0x7fede406f1f0 "x\005", size=size@entry=2048) at libavformat/aviobuf.c:564
#10 0x00000000017441e9 in av_probe_input_buffer2 (pb=0x7fede4059a60, fmt=0x7fededd61b58, filename=<optimized out>, logctx=0x0, offset=0, max_probe_size=1048576) at libavformat/format.c:282
#11 0x00000000017443f9 in av_probe_input_buffer (pb=<optimized out>, fmt=<optimized out>, filename=<optimized out>, logctx=<optimized out>, offset=<optimized out>, max_probe_size=<optimized out>) at libavformat/format.c:336
#12 0x000000000094ca69 in CDVDDemuxFFmpeg::Open (this=this@entry=0x7fede4015dc0, pInput=pInput@entry=0x7fede4027b50, streaminfo=streaminfo@entry=true, fileinfo=fileinfo@entry=false) at DVDDemuxFFmpeg.cpp:289
#13 0x00000000009468f8 in CDVDFactoryDemuxer::CreateDemuxer (pInputStream=0x7fede4027b50, fileinfo=fileinfo@entry=false) at DVDFactoryDemuxer.cpp:134
#14 0x00000000018dcb33 in CDVDPlayer::OpenDemuxStream (this=this@entry=0x95407e0) at DVDPlayer.cpp:797
#15 0x00000000018e5573 in CDVDPlayer::Process (this=0x95407e0) at DVDPlayer.cpp:1117

Thread 32 (Thread 0x7fedaeffd700 (LWP 5088)):
...
#15 0x0000000000fda72d in PVR::CPVRClient::CloseStream (this=0x7fedcc000c40) at PVRClient.cpp:1772
#16 0x0000000000fe454e in PVR::CPVRClients::CloseStream (this=0x7fede0000ad0) at PVRClients.cpp:1538
#17 0x0000000000c79fe1 in PVR::CPVRManager::CloseStream (this=0x237d3e0 <PVR::CPVRManager::Get()::pvrManagerInstance>) at PVRManager.cpp:1090
#18 0x000000000095ec4a in CDVDInputStreamPVRManager::Close (this=this@entry=0x7fed84008f10) at DVDInputStreamPVRManager.cpp:151
#19 0x000000000095ed04 in CDVDInputStreamPVRManager::~CDVDInputStreamPVRManager (this=0x7fed84008f10, __in_chrg=<optimized out>) at DVDInputStreamPVRManager.cpp:57
#20 0x000000000095edc9 in CDVDInputStreamPVRManager::~CDVDInputStreamPVRManager (this=0x7fed84008f10, __in_chrg=<optimized out>) at DVDInputStreamPVRManager.cpp:58
#21 0x000000000091d434 in CDVDFileInfo::GetFileStreamDetails (pItem=pItem@entry=0x7fede40d57d0) at DVDFileInfo.cpp:360
#22 0x0000000000861942 in CThumbExtractor::DoWork (this=0x7fede40d57b0) at VideoThumbLoader.cpp:135
#23 0x0000000000f4fe59 in CJobWorker::Process (this=0x45e22c0) at JobManager.cpp:68
d941413

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Jan 11, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: refresh m_item pointer even if nothing has c…
…hanged

The method UpdateItems() calls ClearGridIndex() (via Reset()), which
invalidates all pointers into m_gridIndex.  Now m_item points to
invalidated memory.  UpdateItems() takes care for updating m_item, but
only if it believes that something has changed.  There are two code
paths that return from UpdateItems() without refreshing m_item, and
this will eventually crash Kodi in the next Update() invocation.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x7f1ffa641bb8 at pc 0x000000dfc890 bp 0x7fffa072a930 sp 0x7fffa072a928
READ of size 4 at 0x7f1ffa641bb8 thread T0
    #0 0xdfc88f in EPG::CGUIEPGGridContainer::GetItemSize(EPG::GridItemsPtr*) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1652
    #1 0xe08a0d in EPG::CGUIEPGGridContainer::SetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1224
    #2 0xe09222 in EPG::CGUIEPGGridContainer::SetSelectedChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1424
    #3 0xe0dada in EPG::CGUIEPGGridContainer::SetChannel(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1199
    #4 0x17d4de6 in PVR::CGUIWindowPVRGuide::Update(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:157
    #5 0x141283e in CGUIMediaWindow::Refresh(bool) /home/max/git/kodi/xbmc/windows/GUIMediaWindow.cpp:868
    #6 0x17d64da in PVR::CGUIWindowPVRGuide::OnMessage(CGUIMessage&) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:363
    #7 0x8c8e00 in CGUIWindowManager::SendMessage(CGUIMessage&) /home/max/git/kodi/xbmc/guilib/GUIWindowManager.cpp:505
    #8 0x8c8f7a in CGUIWindowManager::SendMessage(CGUIMessage&, int) /home/max/git/kodi/xbmc/guilib/GUIWindowManager.cpp:515
    #9 0x8d1d48 in CGUIWindowManager::OnApplicationMessage(KODI::MESSAGING::ThreadMessage*) /home/max/git/kodi/xbmc/guilib/GUIWindowManager.cpp:902
    #10 0x107ebc0 in KODI::MESSAGING::CApplicationMessenger::ProcessMessage(KODI::MESSAGING::ThreadMessage*) /home/max/git/kodi/xbmc/messaging/ApplicationMessenger.cpp:232
    #11 0x107f97f in KODI::MESSAGING::CApplicationMessenger::ProcessWindowMessages() /home/max/git/kodi/xbmc/messaging/ApplicationMessenger.cpp:251
    #12 0x146e144 in CApplication::Process() /home/max/git/kodi/xbmc/Application.cpp:4505
    #13 0x159891d in CXBApplicationEx::Run() /home/max/git/kodi/xbmc/XBApplicationEx.cpp:99
    #14 0x15a35d0 in XBMC_Run /home/max/git/kodi/xbmc/xbmc.cpp:108
    #15 0x6e91b1 in main /home/max/git/kodi/xbmc/main/main.cpp:79
    #16 0x7f203053486f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2086f)
    #17 0x6e8e68 in _start (/usr/local/stow/kodi/lib/kodi/kodi.bin+0x6e8e68)
33ab3b0

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Jan 11, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
a4bcda6

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Jan 11, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: refresh m_item pointer even if nothing has c…
…hanged

The method UpdateItems() calls ClearGridIndex() (via Reset()), which
invalidates all pointers into m_gridIndex.  Now m_item points to
invalidated memory.  UpdateItems() takes care for updating m_item, but
only if it believes that something has changed.  There are two code
paths that return from UpdateItems() without refreshing m_item, and
this will eventually crash Kodi in the next Update() invocation.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x7f1ffa641bb8 at pc 0x000000dfc890 bp 0x7fffa072a930 sp 0x7fffa072a928
READ of size 4 at 0x7f1ffa641bb8 thread T0
    #0 0xdfc88f in EPG::CGUIEPGGridContainer::GetItemSize(EPG::GridItemsPtr*) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1652
    #1 0xe08a0d in EPG::CGUIEPGGridContainer::SetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1224
    #2 0xe09222 in EPG::CGUIEPGGridContainer::SetSelectedChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1424
    #3 0xe0dada in EPG::CGUIEPGGridContainer::SetChannel(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1199
    #4 0x17d4de6 in PVR::CGUIWindowPVRGuide::Update(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:157
    #5 0x141283e in CGUIMediaWindow::Refresh(bool) /home/max/git/kodi/xbmc/windows/GUIMediaWindow.cpp:868
    #6 0x17d64da in PVR::CGUIWindowPVRGuide::OnMessage(CGUIMessage&) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:363
    #7 0x8c8e00 in CGUIWindowManager::SendMessage(CGUIMessage&) /home/max/git/kodi/xbmc/guilib/GUIWindowManager.cpp:505
    #8 0x8c8f7a in CGUIWindowManager::SendMessage(CGUIMessage&, int) /home/max/git/kodi/xbmc/guilib/GUIWindowManager.cpp:515
    #9 0x8d1d48 in CGUIWindowManager::OnApplicationMessage(KODI::MESSAGING::ThreadMessage*) /home/max/git/kodi/xbmc/guilib/GUIWindowManager.cpp:902
    #10 0x107ebc0 in KODI::MESSAGING::CApplicationMessenger::ProcessMessage(KODI::MESSAGING::ThreadMessage*) /home/max/git/kodi/xbmc/messaging/ApplicationMessenger.cpp:232
    #11 0x107f97f in KODI::MESSAGING::CApplicationMessenger::ProcessWindowMessages() /home/max/git/kodi/xbmc/messaging/ApplicationMessenger.cpp:251
    #12 0x146e144 in CApplication::Process() /home/max/git/kodi/xbmc/Application.cpp:4505
    #13 0x159891d in CXBApplicationEx::Run() /home/max/git/kodi/xbmc/XBApplicationEx.cpp:99
    #14 0x15a35d0 in XBMC_Run /home/max/git/kodi/xbmc/xbmc.cpp:108
    #15 0x6e91b1 in main /home/max/git/kodi/xbmc/main/main.cpp:79
    #16 0x7f203053486f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2086f)
    #17 0x6e8e68 in _start (/usr/local/stow/kodi/lib/kodi/kodi.bin+0x6e8e68)
4ab122d

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Jan 11, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
e006f83

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Jan 11, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: refresh m_item pointer even if nothing has c…
…hanged

The method UpdateItems() calls ClearGridIndex() (via Reset()), which
invalidates all pointers into m_gridIndex.  Now m_item points to
invalidated memory.  UpdateItems() takes care for updating m_item, but
only if it believes that something has changed.  There are two code
paths that return from UpdateItems() without refreshing m_item, and
this will eventually crash Kodi in the next Update() invocation.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x7f1ffa641bb8 at pc 0x000000dfc890 bp 0x7fffa072a930 sp 0x7fffa072a928
READ of size 4 at 0x7f1ffa641bb8 thread T0
    #0 0xdfc88f in EPG::CGUIEPGGridContainer::GetItemSize(EPG::GridItemsPtr*) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1652
    #1 0xe08a0d in EPG::CGUIEPGGridContainer::SetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1224
    #2 0xe09222 in EPG::CGUIEPGGridContainer::SetSelectedChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1424
    #3 0xe0dada in EPG::CGUIEPGGridContainer::SetChannel(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1199
    #4 0x17d4de6 in PVR::CGUIWindowPVRGuide::Update(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:157
    #5 0x141283e in CGUIMediaWindow::Refresh(bool) /home/max/git/kodi/xbmc/windows/GUIMediaWindow.cpp:868
    #6 0x17d64da in PVR::CGUIWindowPVRGuide::OnMessage(CGUIMessage&) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:363
    #7 0x8c8e00 in CGUIWindowManager::SendMessage(CGUIMessage&) /home/max/git/kodi/xbmc/guilib/GUIWindowManager.cpp:505
    #8 0x8c8f7a in CGUIWindowManager::SendMessage(CGUIMessage&, int) /home/max/git/kodi/xbmc/guilib/GUIWindowManager.cpp:515
    #9 0x8d1d48 in CGUIWindowManager::OnApplicationMessage(KODI::MESSAGING::ThreadMessage*) /home/max/git/kodi/xbmc/guilib/GUIWindowManager.cpp:902
    #10 0x107ebc0 in KODI::MESSAGING::CApplicationMessenger::ProcessMessage(KODI::MESSAGING::ThreadMessage*) /home/max/git/kodi/xbmc/messaging/ApplicationMessenger.cpp:232
    #11 0x107f97f in KODI::MESSAGING::CApplicationMessenger::ProcessWindowMessages() /home/max/git/kodi/xbmc/messaging/ApplicationMessenger.cpp:251
    #12 0x146e144 in CApplication::Process() /home/max/git/kodi/xbmc/Application.cpp:4505
    #13 0x159891d in CXBApplicationEx::Run() /home/max/git/kodi/xbmc/XBApplicationEx.cpp:99
    #14 0x15a35d0 in XBMC_Run /home/max/git/kodi/xbmc/xbmc.cpp:108
    #15 0x6e91b1 in main /home/max/git/kodi/xbmc/main/main.cpp:79
    #16 0x7f203053486f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2086f)
    #17 0x6e8e68 in _start (/usr/local/stow/kodi/lib/kodi/kodi.bin+0x6e8e68)
e6f2bfb

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Jan 11, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
d01bc6e

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Jan 11, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: refresh m_item pointer even if nothing has c…
…hanged

The method UpdateItems() calls ClearGridIndex() (via Reset()), which
invalidates all pointers into m_gridIndex.  Now m_item points to
invalidated memory.  UpdateItems() takes care for updating m_item, but
only if it believes that something has changed.  There are two code
paths that return from UpdateItems() without refreshing m_item, and
this will eventually crash Kodi in the next Update() invocation.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x7f1ffa641bb8 at pc 0x000000dfc890 bp 0x7fffa072a930 sp 0x7fffa072a928
READ of size 4 at 0x7f1ffa641bb8 thread T0
    #0 0xdfc88f in EPG::CGUIEPGGridContainer::GetItemSize(EPG::GridItemsPtr*) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1652
    #1 0xe08a0d in EPG::CGUIEPGGridContainer::SetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1224
    #2 0xe09222 in EPG::CGUIEPGGridContainer::SetSelectedChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1424
    #3 0xe0dada in EPG::CGUIEPGGridContainer::SetChannel(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1199
    #4 0x17d4de6 in PVR::CGUIWindowPVRGuide::Update(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:157
    #5 0x141283e in CGUIMediaWindow::Refresh(bool) /home/max/git/kodi/xbmc/windows/GUIMediaWindow.cpp:868
    #6 0x17d64da in PVR::CGUIWindowPVRGuide::OnMessage(CGUIMessage&) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:363
    #7 0x8c8e00 in CGUIWindowManager::SendMessage(CGUIMessage&) /home/max/git/kodi/xbmc/guilib/GUIWindowManager.cpp:505
    #8 0x8c8f7a in CGUIWindowManager::SendMessage(CGUIMessage&, int) /home/max/git/kodi/xbmc/guilib/GUIWindowManager.cpp:515
    #9 0x8d1d48 in CGUIWindowManager::OnApplicationMessage(KODI::MESSAGING::ThreadMessage*) /home/max/git/kodi/xbmc/guilib/GUIWindowManager.cpp:902
    #10 0x107ebc0 in KODI::MESSAGING::CApplicationMessenger::ProcessMessage(KODI::MESSAGING::ThreadMessage*) /home/max/git/kodi/xbmc/messaging/ApplicationMessenger.cpp:232
    #11 0x107f97f in KODI::MESSAGING::CApplicationMessenger::ProcessWindowMessages() /home/max/git/kodi/xbmc/messaging/ApplicationMessenger.cpp:251
    #12 0x146e144 in CApplication::Process() /home/max/git/kodi/xbmc/Application.cpp:4505
    #13 0x159891d in CXBApplicationEx::Run() /home/max/git/kodi/xbmc/XBApplicationEx.cpp:99
    #14 0x15a35d0 in XBMC_Run /home/max/git/kodi/xbmc/xbmc.cpp:108
    #15 0x6e91b1 in main /home/max/git/kodi/xbmc/main/main.cpp:79
    #16 0x7f203053486f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2086f)
    #17 0x6e8e68 in _start (/usr/local/stow/kodi/lib/kodi/kodi.bin+0x6e8e68)
bba54ea

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Jan 11, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
654e341

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Jan 13, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: refresh m_item pointer even if nothing has c…
…hanged

The method UpdateItems() calls ClearGridIndex() (via Reset()), which
invalidates all pointers into m_gridIndex.  Now m_item points to
invalidated memory.  UpdateItems() takes care for updating m_item, but
only if it believes that something has changed.  There are two code
paths that return from UpdateItems() without refreshing m_item, and
this will eventually crash Kodi in the next Update() invocation.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x7f1ffa641bb8 at pc 0x000000dfc890 bp 0x7fffa072a930 sp 0x7fffa072a928
READ of size 4 at 0x7f1ffa641bb8 thread T0
    #0 0xdfc88f in EPG::CGUIEPGGridContainer::GetItemSize(EPG::GridItemsPtr*) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1652
    #1 0xe08a0d in EPG::CGUIEPGGridContainer::SetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1224
    #2 0xe09222 in EPG::CGUIEPGGridContainer::SetSelectedChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1424
    #3 0xe0dada in EPG::CGUIEPGGridContainer::SetChannel(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1199
    #4 0x17d4de6 in PVR::CGUIWindowPVRGuide::Update(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:157
    #5 0x141283e in CGUIMediaWindow::Refresh(bool) /home/max/git/kodi/xbmc/windows/GUIMediaWindow.cpp:868
    #6 0x17d64da in PVR::CGUIWindowPVRGuide::OnMessage(CGUIMessage&) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:363
    #7 0x8c8e00 in CGUIWindowManager::SendMessage(CGUIMessage&) /home/max/git/kodi/xbmc/guilib/GUIWindowManager.cpp:505
    #8 0x8c8f7a in CGUIWindowManager::SendMessage(CGUIMessage&, int) /home/max/git/kodi/xbmc/guilib/GUIWindowManager.cpp:515
    #9 0x8d1d48 in CGUIWindowManager::OnApplicationMessage(KODI::MESSAGING::ThreadMessage*) /home/max/git/kodi/xbmc/guilib/GUIWindowManager.cpp:902
    #10 0x107ebc0 in KODI::MESSAGING::CApplicationMessenger::ProcessMessage(KODI::MESSAGING::ThreadMessage*) /home/max/git/kodi/xbmc/messaging/ApplicationMessenger.cpp:232
    #11 0x107f97f in KODI::MESSAGING::CApplicationMessenger::ProcessWindowMessages() /home/max/git/kodi/xbmc/messaging/ApplicationMessenger.cpp:251
    #12 0x146e144 in CApplication::Process() /home/max/git/kodi/xbmc/Application.cpp:4505
    #13 0x159891d in CXBApplicationEx::Run() /home/max/git/kodi/xbmc/XBApplicationEx.cpp:99
    #14 0x15a35d0 in XBMC_Run /home/max/git/kodi/xbmc/xbmc.cpp:108
    #15 0x6e91b1 in main /home/max/git/kodi/xbmc/main/main.cpp:79
    #16 0x7f203053486f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2086f)
    #17 0x6e8e68 in _start (/usr/local/stow/kodi/lib/kodi/kodi.bin+0x6e8e68)
b49f6f0

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Jan 13, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
0571431

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Jan 15, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: refresh m_item pointer even if nothing has c…
…hanged

The method UpdateItems() calls ClearGridIndex() (via Reset()), which
invalidates all pointers into m_gridIndex.  Now m_item points to
invalidated memory.  UpdateItems() takes care for updating m_item, but
only if it believes that something has changed.  There are two code
paths that return from UpdateItems() without refreshing m_item, and
this will eventually crash Kodi in the next Update() invocation.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x7f1ffa641bb8 at pc 0x000000dfc890 bp 0x7fffa072a930 sp 0x7fffa072a928
READ of size 4 at 0x7f1ffa641bb8 thread T0
    #0 0xdfc88f in EPG::CGUIEPGGridContainer::GetItemSize(EPG::GridItemsPtr*) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1652
    #1 0xe08a0d in EPG::CGUIEPGGridContainer::SetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1224
    #2 0xe09222 in EPG::CGUIEPGGridContainer::SetSelectedChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1424
    #3 0xe0dada in EPG::CGUIEPGGridContainer::SetChannel(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1199
    #4 0x17d4de6 in PVR::CGUIWindowPVRGuide::Update(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:157
    #5 0x141283e in CGUIMediaWindow::Refresh(bool) /home/max/git/kodi/xbmc/windows/GUIMediaWindow.cpp:868
    #6 0x17d64da in PVR::CGUIWindowPVRGuide::OnMessage(CGUIMessage&) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:363
    #7 0x8c8e00 in CGUIWindowManager::SendMessage(CGUIMessage&) /home/max/git/kodi/xbmc/guilib/GUIWindowManager.cpp:505
    #8 0x8c8f7a in CGUIWindowManager::SendMessage(CGUIMessage&, int) /home/max/git/kodi/xbmc/guilib/GUIWindowManager.cpp:515
    #9 0x8d1d48 in CGUIWindowManager::OnApplicationMessage(KODI::MESSAGING::ThreadMessage*) /home/max/git/kodi/xbmc/guilib/GUIWindowManager.cpp:902
    #10 0x107ebc0 in KODI::MESSAGING::CApplicationMessenger::ProcessMessage(KODI::MESSAGING::ThreadMessage*) /home/max/git/kodi/xbmc/messaging/ApplicationMessenger.cpp:232
    #11 0x107f97f in KODI::MESSAGING::CApplicationMessenger::ProcessWindowMessages() /home/max/git/kodi/xbmc/messaging/ApplicationMessenger.cpp:251
    #12 0x146e144 in CApplication::Process() /home/max/git/kodi/xbmc/Application.cpp:4505
    #13 0x159891d in CXBApplicationEx::Run() /home/max/git/kodi/xbmc/XBApplicationEx.cpp:99
    #14 0x15a35d0 in XBMC_Run /home/max/git/kodi/xbmc/xbmc.cpp:108
    #15 0x6e91b1 in main /home/max/git/kodi/xbmc/main/main.cpp:79
    #16 0x7f203053486f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2086f)
    #17 0x6e8e68 in _start (/usr/local/stow/kodi/lib/kodi/kodi.bin+0x6e8e68)
493d0d7

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Jan 15, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
82782df

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Jan 16, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
93990e5

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Jan 16, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
6860bd8

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Jan 16, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
04c5766

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Jan 17, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
a101cdc

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Jan 18, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
671561f

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Jan 19, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
f670068

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Jan 19, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
34c7d31

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Jan 20, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
3b7008d

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Jan 22, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
43fbeb5

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Jan 25, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
b07caff

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Jan 27, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
b48a7c3

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Jan 30, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
ec62416

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Jan 30, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
17357a9

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Jan 31, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
c73ee48

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Jan 31, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
2ac23f4

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Jan 31, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
b61619e

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Feb 1, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
d89fa56

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Feb 2, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
ab2166d

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Feb 2, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
fde1c1a

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Feb 2, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
1f72964

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Feb 2, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
996fd43

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Feb 2, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
9765d2c

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Feb 3, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
83313fa

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Feb 3, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
9a1c726

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Feb 3, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
e73c6fb

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Feb 3, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
0cf8ebf

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Feb 4, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
8bcebe1

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Feb 4, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
289e75f

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Feb 4, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
ebca3d3

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Feb 4, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
8eea29a

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Feb 4, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
b93ec94

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Feb 4, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
3e8b269

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Feb 5, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
d6dd828

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Feb 5, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
120b159

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Feb 9, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
2a4233d

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Feb 9, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
09eb332

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Feb 11, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
95cf02e

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Feb 12, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
6548b7f

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Feb 13, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
c89e4a8

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Feb 14, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
8662b01

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Feb 15, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
4c5d45e

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Feb 16, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
a59a0dc

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Feb 16, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
24fcc91

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Feb 17, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
01b953e

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Feb 18, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
1b802be

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Feb 19, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
64eaf55

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Feb 20, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
9389552

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Feb 21, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
f3c4fe5

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Feb 22, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
9aad5d2

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Feb 23, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
3ec2269

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Feb 25, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
7786b90

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Feb 28, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
19ca6b9

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Feb 29, 2016

@MaxKellermann MaxKellermann epg/GUIEPGGridContainer: add missing CSingleLock in GetChannel(int)
Fixes random crashes when UpdateItems() runs while another thread
invokes CGUIWindowPVRGuide::UpdateSelectedItemPath() (via
CGUIWindowPVRBase::Notify() called by CEpgContainer::Notify()).
UpdateItems() invalidates m_channelItems and its items, while
GetChannel() dereferences one channel item.

This is how the crash looks like with gcc's AddressSanitizer:

ERROR: AddressSanitizer: heap-use-after-free on address 0x603001b025c8 at pc 0x000000e04b2a bp 0x7f8f8997abf0 sp 0x7f8f8997abe8
WRITE of size 4 at 0x603001b025c8 thread T19 (EPGUpdater)
    #0 0xe04b29 in __atomic_add /usr/include/c++/5/ext/atomicity.h:53
    #1 0xe04b29 in __atomic_add_dispatch /usr/include/c++/5/ext/atomicity.h:96
    #2 0xe04b29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_copy() /usr/include/c++/5/bits/shared_ptr_base.h:134
    #3 0xe04b29 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:666
    #4 0xe04b29 in std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__shared_ptr<CFileItem, (__gnu_cxx::_Lock_policy)2> const&) /usr/include/c++/5/bits/shared_ptr_base.h:923
    #5 0xe04b29 in std::shared_ptr<CFileItem>::shared_ptr(std::shared_ptr<CFileItem> const&) /usr/include/c++/5/bits/shared_ptr.h:107
    #6 0xe04b29 in EPG::CGUIEPGGridContainer::GetChannel(int) /home/max/git/kodi/xbmc/epg/GUIEPGGridContainer.cpp:1411
    #7 0x17d84c2 in PVR::CGUIWindowPVRGuide::UpdateSelectedItemPath() /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRGuide.cpp:140
    #8 0x17c8f7d in PVR::CGUIWindowPVRBase::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/pvr/windows/GUIWindowPVRBase.cpp:90
    #9 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #10 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #11 0xdf16d2 in EPG::CEpgContainer::Notify(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:212
    #12 0x16b3566 in Observable::SendMessage(Observable const&, ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:149
    #13 0x16b385e in Observable::NotifyObservers(ObservableMessage) /home/max/git/kodi/xbmc/utils/Observer.cpp:129
    #14 0xde370d in EPG::CEpg::UpdateEntries(EPG::CEpg const&, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:397
    #15 0xde38e5 in EPG::CEpg::LoadFromClients(long, long) /home/max/git/kodi/xbmc/epg/Epg.cpp:751
    #16 0xde4132 in EPG::CEpg::Update(long, long, int, bool) /home/max/git/kodi/xbmc/epg/Epg.cpp:464
    #17 0xdec052 in EPG::CEpgContainer::UpdateEPG(bool) /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:665
    #18 0xdf05e5 in EPG::CEpgContainer::Process() /home/max/git/kodi/xbmc/epg/EpgContainer.cpp:364
    #19 0x1a7d05e in CThread::Action() /home/max/git/kodi/xbmc/threads/Thread.cpp:221
    #20 0x1a7d565 in CThread::staticThread(void*) /home/max/git/kodi/xbmc/threads/Thread.cpp:131
    #21 0x7f8fb2582283 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7283)
    #22 0x7f8faa78174c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe874c)
7bc7e9f

@MaxKellermann MaxKellermann added a commit to MaxKellermann/xbmc that referenced this pull request Feb 29, 2016

@MaxKellermann MaxKellermann