Which thread to call uploadTask from URLSession

Hi, I would like to know if it is safe to call the uploadTask from URLSession from the main thread ?

We've a user who is reporting repeated crashes at startup, here is the stack we see:

Exception Type:  EXC_CRASH (SIGKILL)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Termination Reason: FRONTBOARD 2343432205 
<RBSTerminateContext| domain:10 code:0x8BADF00D explanation:scene-update watchdog transgression: app<com.appspot.myApp(E7590BB1-722C-491D-9199-F867DE4B880A)>:2212 exhausted real (wall clock) time allowance of 10.00 seconds
ProcessVisibility: Background
ProcessState: Running
WatchdogEvent: scene-update
WatchdogVisibility: Background
WatchdogCPUStatistics: (
"Elapsed total CPU time (seconds): 21.260 (user 10.230, system 11.030), 35% CPU",
"Elapsed application CPU time (seconds): 0.006, 0% CPU"
) reportType:CrashLog maxTerminationResistance:Interactive>

Triggered by Thread:  0

Thread 0 name:   Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   libsystem_kernel.dylib        	       0x1def7a688 mach_msg2_trap + 8
1   libsystem_kernel.dylib        	       0x1def7dd98 mach_msg2_internal + 80
2   libsystem_kernel.dylib        	       0x1def7dcb0 mach_msg_overwrite + 424
3   libsystem_kernel.dylib        	       0x1def7dafc mach_msg + 24
4   libdispatch.dylib             	       0x1968d8f14 _dispatch_mach_send_and_wait_for_reply + 544
5   libdispatch.dylib             	       0x1968d92b4 dispatch_mach_send_with_result_and_wait_for_reply + 60
6   libxpc.dylib                  	       0x21714a930 xpc_connection_send_message_with_reply_sync + 256
7   Foundation                    	       0x18d80a3ac __NSXPCCONNECTION_IS_WAITING_FOR_A_SYNCHRONOUS_REPLY__ + 16
8   Foundation                    	       0x18d806b14 -[NSXPCConnection _sendInvocation:orArguments:count:methodSignature:selector:withProxy:] + 2160
9   CoreFoundation                	       0x18eb868dc ___forwarding___ + 1004
10  CoreFoundation                	       0x18eb86430 _CF_forwarding_prep_0 + 96
11  CFNetwork                     	       0x1900c71e0 -[__NSURLBackgroundSession setupBackgroundSession] + 800
12  CFNetwork                     	       0x1900b3e80 -[__NSURLBackgroundSession initWithConfiguration:delegate:delegateQueue:delegateDispatchQueue:] + 552
13  CFNetwork                     	       0x1900b4784 +[NSURLSession _sessionWithConfiguration:delegate:delegateQueue:delegateDispatchQueue:] + 1496
14  MyApp                        	       0x1054210b4 CombineBgXferRepository.session.getter (in MyApp) (CombineBgXferRepository.swift:62) + 7966900
15  MyApp                        	       0x105422fa4 CombineBgXferRepository.startUploadTask(fileURL:request:) (in MyApp) (CombineBgXferRepository.swift:310) + 7974820

If it is ok to call this uploadTask from the main thread, does this crash indicate a problem with the operating system? Are there scenarios where the background upload service does not respond to requests?

Apple has historically not shipped APIs that are blocking -- if so, they are marked as async or include some kind of callback. As a result, I believe that this indicates some kind of problem with the operating system and potentially a bug that should be reported to Apple...?

We've a user who is reporting repeated crashes at startup, here is the stack we see:

Please post the full crash log using these instructions. From long experience, all but the simplest of crash logs can't really be diagnosed without the larger context of the full log. I could come up with a variety of explanation for that stack, all of which would be completely invalidated by activity on other threads.

Hi, I would like to know if it is safe to call the uploadTask from URLSession from the main thread ?

Yes, I would generally consider it safe, as it shouldn't be blocking for any significant period of time.

If it is ok to call this uploadTask from the main thread, does this crash indicate a problem with the operating system?

There's no way to know that given the information that stack trace. More specifically, looking ONLY at that crash stack:

-The assumption here is that you blocked here*:

11  CFNetwork                     	       0x1900c71e0 -[__NSURLBackgroundSession setupBackgroundSession] + 800

*Everything above that point are the more general functions the system uses for XPC communication, which means they're SO broadly used that you can basically treat them as "bug free".

That assumption could very well be true, but you don't actually know that. The crash log you're looking at was generated at the moment the system terminated your app and ONLY shows you what your app was doing at that moment, NOT what is was doing "before" that. If an app spends 4.9s blocked in foo() and then blocks in bar() for 0.1s, every termination log will blame "bar()", even though "foo()" is in fact the problem.

-You don't know WHY you blocked there at all. If the system blocked then that COULD be an OS problem, but if YOU blocked there then the problem is "you" (see below).

That leads to here:

Are there scenarios where the background upload service does not respond to requests?

No, at least not in the straightforward senses of "if you do this, then this crash happens". The background URL session is very heavily used and that means "straightforward" bugs are relatively rare, simply because they cause so many problems.

However, putting on my Psychic Debugging Hat™, the first question I would ask is what, if any, analytics services your app includes. The XPC call in that stack shouldn't have blocked for any significant period of time, so IF it blocked, one of two things was happening:

  1. And issue on the system side meant that the daemon (nsurlsessiond) was unable to respond for a "long" ("seconds") time.

  2. Your app prevented the thread from executing.

Behind the scenes, many analytics libraries collect data by suspending the thread(s), capturing a stack trace, and then resuming the thread. That process is FAR more dangerous than it sounds and if/when something goes wrong, this is the kind of failure it often generates.

__
Kevin Elliott
DTS Engineering, CoreOS/Hardware

Hi, I'm attaching a full crash stack trace. There is indeed a thread that might seem suspicious.

Thread 3 name:  com.google.firebase.crashlytics.MachExceptionServer
Thread 3:

Which thread to call uploadTask from URLSession
 
 
Q