Search code examples
iosswiftcrashqos

iOS - How to understand and properly debug this type of crash : com.apple.root.background-qos?


I know this question has been already asked several times, but either it stayed unanswered or the answer was totally not helping.

Here is my crash report :

enter image description here

This question and especially the comments helped me understand (kind of) my issue.

It seems from your crash log com.apple.root.background-qos, this is the thread request which might be over committed due to which it exist as it cannot take any more request.

If I understand it correctly, it may be possible that the thread handling requests might not be able to handle more requests ?

How do I debug and test this ? I am unable to reproduce the crash.

NB: In my launcher service I am doing 5 or 6 requests each one separated in a dispatchGroup.enter / .leave when finished, like this :

dispatchGroup.enter()
self.fetchObservationForecast(lat: lat, lon: lon) { result in
     switch result {
     case .success(let observationForecast) :
          print("Observation Forecast request succeeded")
          model["observationForecast"] = observationForecast
          break
     case .failure(let error) :
          print("Observation Forecast request failed : \(error)")
          model["observationForecast"] = error
          break
     }
     dispatchGroup.leave()
}

Am I looking at the wrong place ? How can I test and reproduce it in order to submit a fix ?

Any help would be appreciated.


Solution

  • The crash is coming from something in the closures in the LauncherService methods indicated. The trace indicates that you're crashing on setting a Dictionary value.

    PartialStackTrace

    Mutable Swift Dictionaries are not thread-safe, and that fact along with the background.qos indictor make me think you're reading/writing a Dictionary on multiple threads.

    It's probably something like the model["observationForecast"] = code below doing that.

    dispatchGroup.enter()
    self.fetchObservationForecast(lat: lat, lon: lon) { result in
         switch result {
         case .success(let observationForecast) :
              print("Observation Forecast request succeeded")
              model["observationForecast"] = observationForecast
              break
         case .failure(let error) :
              print("Observation Forecast request failed : \(error)")
              model["observationForecast"] = error
              break
         }
         dispatchGroup.leave()
    }