-
Notifications
You must be signed in to change notification settings - Fork 16
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
Crash on Getstream AuthorizationMoyaPlugin #19
Comments
thank you for opening this issue, the suggested change makes sense (worst case it will not solve the problem you are facing but it won't do any harm). If you want to speed things up, I suggest opening a PR with this code change :) |
Any update on the issue? |
Please @tbarbugli can you give a bit of ❤️ to this one? |
@tbarbugli any plan to fix this? it is by far the main cause of our app crashes, 10x more frequent than our next crash reports (The previous commit did not fix the issue) |
Hi @angelolloqui! I'm not very familiar with the codebase yet, but looking at the crash log, this issue does not seem related to our SDK. Doing a quick research, this could actually be related to an SDK you might be using that is doing runtime swizzling on the URLSession, at least according to this issue: Alamofire/Alamofire#3515. Are you using any third-party SDK for analytics or crashlytics? This could be anything like Firebase, Sentry, Datadog, etc... Best, |
Hi @nuno-vieira , I appreciate your answer and you having some time to look at it. However, I am not sure I am following your comment because the fact that a string is a value type does not guarantee thread safety. In fact, it is a common belief that value types are copied but they are most of the times not, just because of compilation optimizations. You can read about thread safety (or lack of) in value types here: https://forums.swift.org/t/understanding-swifts-value-type-thread-safety/41406/6 My guess (I am not familiar with the code either) is that you are changing the token from a different thread without synchronizing the read/write operation, resulting in rare but possible crashes when read and write operations are happening in parallel. I will check the link you provided more closely but in a first quick look it seems an unrelated issue, not having the same stack trace. Besides, if it would be due to swizzling it would affect all calls in the app since we make heavy use of urlsessions ourselves but it is only happening in the moya plug-in. thanks! |
Hi @angelolloqui, I'm familiar with thread safety, and I didn't say value types avoided thread safety issues. If you read the stack trace, you can see the crash happens inside the |
Hi @nuno-vieira, once again thanks for replying that quickly. I see your point in that it is happening inside the However, as I know you are probably not convinced by my argument (I would not be), let me share you a different stack trace of the crash:
As you can see here, the crash is this time happening directly in the Once again, this is a tricky one and I might be mistaken, but I am quite confident than the problem is caused by the GetStream code because of a threading issue. As I said, I am not familiar with the code, but I will try to dig inside it, because I expect some kind of manipulation of the token variable from a different thread (this one is a background one) without synchronization primitives. I hope this brings some extra light to it... I will get back with some actual code when I get time to dig into your library, but I appreciate if you could also check for token manipulation places and threading from where it is happening. Thanks again! |
Hi @angelolloqui, I find it really hard for this to be the issue. You can even test this yourself and see that the following test below doesn't crash: func test_token_isThreadSafe() {
let plugin = AuthorizationMoyaPlugin()
for index in 0...1000 {
plugin.token = String(index)
}
DispatchQueue.concurrentPerform(iterations: 1000) { _ in
_ = plugin.token
plugin.token = "Hey"
}
DispatchQueue.concurrentPerform(iterations: 1000) { _ in
_ = plugin.prepare(URLRequest(url: URL(string: "url")!))
}
} In that test, we are reading and writing the token in multiple threads, and we are also calling Either way, it would be nice if you could research as well if there is any SDK in your app that could be causing this, and try to update all of your SDKs. If after you update your SDKs the issue still persists then most likely could be true that the issue is on our side. We will then make the moya plugin thread-safe or re-configure moya whenever the token changes. I'll speak with the team internally, and will give you an ETA for this as soon as possible. Best, |
Hi @nuno-vieira , very interesting discussion. And actually, you had a great idea with your test. I made a few changes to your test:
I am doing this to force the read and write access to be executed in parallel (in your version, I think the concurrency happens inside each block, but not accross the read/writes). With this test, I am not getting a crash either, but when you activate the thread sanitizer you can see this output:
As you can see, it detects the data race due to threading. Why it does not crash in test? I am not sure, but my guess is that the compilation options have something to do here, since for tests we do not have the full optimization options that are provided in final builds and that might remove "unnecessary" retain/releases (causing the crash in this case). Again, it is just a guess, but at least now with the thread sanitiser we can see something more "palpable" |
UPDATE: With the previous test, I tried setting some sync primitives like this:
And now the ThreadSanitizer issue is gone. Code is not looking great, but at least you can see how this seems to prevent the data race. I hope it helps! |
@angelolloqui Nice catch! Yes, that is a pretty standard way to make it thread-safe. Although, when updating the token, it doesn't need to block the thread. This could be an issue if you are updating the token from the main thread for example. I've opened the PR here: GetStream/stream-swift#44 |
Closing the issue since it is being tracked here: GetStream/stream-swift#44 And it is now available on 2.2.5 |
We are getting several crashes on production from the class
AuthorizationMoyaPlugin
in GetStream library.The crash report is:
It seems the
token
variable is not correct when setting this value in the request.I am checking the code and I do not see any wrong thing, except that token is an instance variable that might change and produce a race condition between the
if token.isEmpty
and the actual usage. Not sure if it helps, but maybe rewriting it to this would protect it:Related info
Xcode 13.0
Crashes detected in several devices, including iOS15 and iOS14
The text was updated successfully, but these errors were encountered: