-
-
Notifications
You must be signed in to change notification settings - Fork 6.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[PVR] Fix crash in PVR::CPVRClient::GetDriveSpace (Trac #15942) #7216
Conversation
for the record: #6732 |
That comment in the second piece of code seems wrong, if it can be mutated by another thread it's not safe to read and absolutely no safe to loop over it |
At best this fix will make the error be more random but it won't fix the underlying issue that you're looping over shared state without a lock |
Sure. Protecting the reading code will avoid the iterator running out of scope. This is probably a better way to take with the problem. But what is the actual root cause? Under which circumstances do multiple cguiinfo threads run in parallel? This imo must be the case to run into the crash. But having more than one of this threada makes no sense for me... Honestly, trying my best, but all this makes not too much sense for me. This drives me nuts! |
The code in void CPVRGUIInfo::UpdateBackendCache(void) makes no sense. Also I'm not really sure that the idea to use a counter to keep track of which client to update is a good idea when storing the clients in a map. Items can change places from under you if something's inserted depending on it's key. activeClients comes from g_PVRClients and is using raw pointers so any change in g_PVRClients can kill this code. That's what I've found so far |
|
quick and dirty possible fix Paxxi/xbmc@83f29c4 @ksooo it seems your first fix could work fine, I was reading on the phone and it looked like it was part of the for loop. |
@Paxxi Did a little more brain debugging and now I understand it. This is not a multithreading issue. Happens also if there is only one guiinfo thread involved and at some certain point in time count of active clients drops. Following scenario:
2nd call to
3rd call to
|
Oops! Close was not intended. @Paxxi: Does my previous comment make sense for you? |
yup @ksooo that's it, you're right that it's actually broken even if there's just one thread involved |
@Paxxi Here is my take on actually fixing the root cause of this bug. Looking okay? |
@ksooo it'll work but I think it would be nicer and easier to read to modify AddonInfoToggle to take the active clients as a param and store it in m_activeClients before doing it's stuff. Should probably be renamed to something else, GetNextUpdateTarget? not that familiar with the code so there's probably a more suitable name for it. |
@Paxxi ofc you are right wrt "nicer and easier to read", but for Isengard at this stage we should avoid any code changes that are not absolutely necessary. Thus, may I suggest to beautify this fix in a separate PR for J****? |
Yeah you can go ahead and merge |
jenkins build this please |
jenkins kodi build successful on all platforms, it was "just" audioencoder.wav that failed to build. |
[PVR] Fix crash in PVR::CPVRClient::GetDriveSpace (Trac #15942)
broke due to earlier refactoring, I suppose when the shared ptrs were introduced here. the idea was that the same thread that registered add-ons were flipping the pointers, and then the rest would be safe to read unlocked. looks like that broke, and this "fix" is a work around for 1 of the situations that can occur now only. |
@opdenkamp you are right. Got the crash today with latest master where this PR already got merged. Must have been one of the other cases you mentioned. :-( |
I'm not 100% sure about the root cause, but the various stack traces I got show that the CPVRClient instance on which GetDriveSpace gets called is NULL. Thus, my simple fix should prevent the crash.
Root cause could be a multithreading issue. One piece of code looks suspicious to me:
For a short moment m_iAddonInfoToggleCurrent can have a value that is too large.
This piece of code reads m_iAddonInfoToggleCurrent without a mutex.
So far so bad, activeClient might point activeClients.end() due to the potential multithreading issue here. But I was unable to actually find out the use case where the writing code runs in another thread than the reading code... strange.
@opdenkamp mind taking a look?