Crash when filling a list from a timer
#1
Hi,

I have random crashes in Kodi and I think it is caused by how I periodically refresh a panel from my C++ code :

I have a class that implements ITimerCallback :

cpp:

class CScreenUpdater : public ITimerCallback
{
    virtual void OnTimeout();

    Timer* m_pTimerWorker;
}

In the constructor, I launch the timer :

cpp:

CScreenUpdater::CScreenUpdater()
{
    m_pTimerWorker = new CTimer(this);

    m_pTimerWorker->Start(5000, true);
}

In the OnTimeout method I do the following

cpp:

void CScreenUpdater::OnTimeout()
{
      // Create the file item list
      CFileItemList mylist;
      mylist = FillItemList();

      // Display it
      CGUIMessage msg(GUI_MSG_LABEL_BIND, WINDOW_HOME, MYLISTID, 0, 0, &mylist);
      CServiceBroker::GetGUI()->GetWindowManager().SendMessage(msg, WINDOW_HOME);
}

MYLISTID is the id of a panel that is defined in my home window

It works sometimes and sometimes it crashes. The exception message is not always the same but it is always related to CFileItem destruction/rendering. Here is a sample crash :

Code:

#1  0x0071445e in CGUIControlGroup::Render() ()
#2  0x0070f224 in CGUIControl:: DoRender() ()
#3  0x0070a476 in CGUIBaseContainer::RenderItem(float, float, CGUIListItem*, bool) ()
#4  0x00729fa4 in CGUIPanelContainer::Render() ()
#5  0x0070f224 in CGUIControl:: DoRender() ()
#6  0x0071445e in CGUIControlGroup::Render() ()
#7  0x0070f224 in CGUIControl:: DoRender() ()
#8  0x007159c2 in CGUIControlGroupList::Render() ()
#9  0x0070f224 in CGUIControl:: DoRender() ()
#10 0x0071445e in CGUIControlGroup::Render() ()
#11 0x0070f224 in CGUIControl:: DoRender() ()
#12 0x0071445e in CGUIControlGroup::Render() ()
#13 0x0070f224 in CGUIControl:: DoRender() ()
#14 0x0071445e in CGUIControlGroup::Render() ()
#15 0x0070f224 in CGUIControl:: DoRender() ()
#16 0x0071445e in CGUIControlGroup::Render() ()
#17 0x0070f224 in CGUIControl:: DoRender() ()
#18 0x0071445e in CGUIControlGroup::Render() ()
#19 0x0070f224 in CGUIControl:: DoRender() ()
#20 0x0071445e in CGUIControlGroup::Render() ()
#21 0x0070f224 in CGUIControl:: DoRender() ()
#22 0x0073947a in CGUIWindow:: DoRender() ()
#23 0x0073c418 in CGUIWindowManager::RenderPass() const ()
#24 0x0073c590 in CGUIWindowManager::Render() ()
#25 0x007d41c0 in CApplication::Render() ()
#26 0x008159aa in CXBApplicationEx::Run(CFileItemList&) ()
#27 0x006e8752 in XBMC_Run ()
#28 0x004d853c in main ()

Here is another example :

Code:

#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1  0x0000007fa03e7788 in __GI_abort () at abort.c:79
#2  0x0000007fa03f285c in __assert_fail_base (fmt=0x7fa04df838 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n",
    assertion=assertion@entry=0x7fa2939070 "INTERNAL_SYSCALL_ERRNO (e, __err) != EDEADLK || (kind != PTHREAD_MUTEX_ERRORCHECK_NP && kind != PTHREAD_MUTEX_RECURSIVE_NP)",
    file=file@entry=0x7fa29392d0 "pthread_mutex_lock.c", line=line@entry=422, function=function@entry=0x7fa29391b8 <__PRETTY_FUNCTION__.10040> "__pthread_mutex_lock_full") at assert.c:92
#3  0x0000007fa03f28c8 in __GI___assert_fail (
    assertion=assertion@entry=0x7fa2939070 "INTERNAL_SYSCALL_ERRNO (e, __err) != EDEADLK || (kind != PTHREAD_MUTEX_ERRORCHECK_NP && kind != PTHREAD_MUTEX_RECURSIVE_NP)",
    file=file@entry=0x7fa29392d0 "pthread_mutex_lock.c", line=line@entry=422, function=function@entry=0x7fa29391b8 <__PRETTY_FUNCTION__.10040> "__pthread_mutex_lock_full") at assert.c:101
#4  0x0000007fa292e9d4 in __pthread_mutex_lock_full (mutex=0x20f6c6b8) at pthread_mutex_lock.c:420
#5  0x0000000000f22560 in ?? ()
#6  0x0000000000b6976c in CGUILargeTextureManager::GetImage(std:: string const&, CTextureArray&, bool, bool) ()
#7  0x0000000000c85e78 in CGUITextureBase::AllocResources() ()
#8  0x0000000000c86190 in CGUITextureBase:: Process(unsigned int) ()
#9  0x0000000000c9a384 in CGUIImage:: Process(unsigned int, std::vector<CDirtyRegion, std::allocator<CDirtyRegion> >&) ()
#10 0x0000000000c9cf4c in CGUIControl:: DoProcess(unsigned int, std::vector<CDirtyRegion, std::allocator<CDirtyRegion> >&) ()
#11 0x0000000000c96c98 in CGUIControlGroup:: Process(unsigned int, std::vector<CDirtyRegion, std::allocator<CDirtyRegion> >&) ()
#12 0x0000000000c9cf4c in CGUIControl:: DoProcess(unsigned int, std::vector<CDirtyRegion, std::allocator<CDirtyRegion> >&) ()
#13 0x0000000000c96c98 in CGUIControlGroup:: Process(unsigned int, std::vector<CDirtyRegion, std::allocator<CDirtyRegion> >&) ()
.....
#29 0x0000000000c96c98 in CGUIControlGroup:: Process(unsigned int, std::vector<CDirtyRegion, std::allocator<CDirtyRegion> >&) ()
#30 0x0000000000c9cf4c in CGUIControl:: DoProcess(unsigned int, std::vector<CDirtyRegion, std::allocator<CDirtyRegion> >&) ()
#31 0x0000000000c67224 in CGUIWindow:: DoProcess(unsigned int, std::vector<CDirtyRegion, std::allocator<CDirtyRegion> >&) ()
#32 0x0000000000c791c4 in CGUIWindowManager:: Process(unsigned int) ()
#33 0x0000000000b98af4 in CApplication::FrameMove(bool, bool) ()
#34 0x0000000000b1f7e4 in CXBApplicationEx::Run(CAppParamParser const&) ()
#35 0x0000000000d04a70 in XBMC_Run ()
#36 0x00000000008b75b8 in main ()

Is is correct to declare the mylist variable as a local variable ? If not, should I allocate my CFileItemList in the heap ? But how to destroy it in that case ?
I tried to declare mylist as a class member (and just clear it and fill it at each timer tick) but it also randomly crashes.

Do I need a lock/unlock mechanism ?
In the source code of KODI, I saw that SendGUIMessage is sometimes used instead of SendMessage.
I also saw some graphics context locking...

Please put me on the right track Smile

Thanks,

Nabil.
Reply

Logout Mark Read Team Forum Stats Members Help
Crash when filling a list from a timer0