aws-sdk-ios icon indicating copy to clipboard operation
aws-sdk-ios copied to clipboard

Crash on [AWSMQTTSession publishDataAtLeastOnce:onTopic:retain:onMessageIdResolved:] when running publish and subscribe actions sequentially

Open matildemarcelletti23 opened this issue 11 months ago • 12 comments

Describe the bug A crash occurs due to a race condition in the [AWSMQTTSession publishDataAtLeastOnce:onTopic:retain:onMessageIdResolved:] function. The issue is caused by concurrent access to the ackCallbackDictionary when running publish and subscribe actions sequentially.

To Reproduce Steps to reproduce the behavior: There is no fixed reproducibility procedure, and crashes occur at irregular intervals but these are the steps I followed:

  1. Connect to AWS IoT
  2. Subscribe and then publish messages on topics with QoS1 in quick succession.
  3. Thread Sanitizer tool on Xcode underlying the possibility of race conditions always on ackCallbackDictionary

Observed Behavior There are two functions involved:

  1. -session:newAckForMessageId:

    • The callback associated with a msgId is returned on a background thread.
    • After execution, the ID is removed from ackCallbackDictionary
  2. (AWSMQTTSession publishDataAtLeastOnce:onTopic:retain:onMessageIdResolved:):

    • A new msgId is generated and added to ackCallbackDictionary with its callback.

    Since both methods access ackCallbackDictionary on different threads without protection, concurrent access may occur.

Stack Trace

   Crashed: com.apple.root.user-initiated-qos.cooperative
0  CoreFoundation                 0x48c48 -[__NSSetM addObject:] + 356
1  AWSIoT                         0x84974 -[AWSMQTTSession publishDataAtLeastOnce:onTopic:retain:onMessageIdResolved:] + 444
2  AWSIoT                         0x60a1c -[AWSIoTMQTTClient publishData:qos:onTopic:retain:ackCallback:] + 628
3  AWSIoT                         0x6067c -[AWSIoTMQTTClient publishString:qos:onTopic:ackCallback:] + 160
4  AWSIoT                         0x8040 -[AWSIoTDataManager publishString:onTopic:QoS:ackCallback:] + 228
5  Infinity                       0x24c3cc IoTDataSource.requestMainShadow(thingName:) + 251 (IoTDataSource.swift:251)
6  Infinity                       0x24a61c IoTDataSource.subscribeToDeviceShadow(thingName:) + 136 (IoTDataSource.swift:136)
7  libswift_Concurrency.dylib     0x60f5c swift::runJobInEstablishedExecutorContext(swift::Job*) + 252
8  libswift_Concurrency.dylib     0x62514 swift_job_runImpl(swift::Job*, swift::SerialExecutorRef) + 144
9  libdispatch.dylib              0x15ec0 _dispatch_root_queue_drain + 392
10 libdispatch.dylib              0x166c4 _dispatch_worker_thread2 + 156
11 libsystem_pthread.dylib        0x3644 _pthread_wqthread + 228
12 libsystem_pthread.dylib        0x1474 start_wqthread + 8

**Areas of the SDK you are using ** AWS IoT

Screenshots

Image

Environment:

  • SDK Version: [2.40.0]
  • Dependency Manager: [Cocoapods]
  • Swift Version : [5.0]
  • Xcode Version: [16.2]

Device Information (please complete the following information):

  • Device: [e.g. iPhone16, Simulator]
  • iOS Version: [e.g. iOS 18.2]

Solution I created a fork where I modified the removal of the ack from the dictionary before calling the callback. This is a temporary workaround to avoid immediate issues, but a permanent fix would require changes to the concurrency management in the AWSIoT library, such as using appropriate synchronization mechanisms for access to the ackCallbackDictionary. Link

matildemarcelletti23 avatar Jan 21 '25 10:01 matildemarcelletti23

Thank you for posting this. We're glad that you have a workaround at the moment.

  • Would you be able to post the verbose logs to help us diagnose the issue better?
  • How often does the issue occur? Is it happening all the time?

thisisabhash avatar Jan 21 '25 17:01 thisisabhash

Hi, the crash rarely occurs while the Thread Sanitizer on Xcode almost always reports the race condition situation I reported above.

I'll leave you below all the logs I managed to get out:

  1. Thread Sanitizer on console prints this:
WARNING: ThreadSanitizer: race on NSMutableDictionary (pid=3517)
  Modifying access of NSMutableDictionary at 0x0001074c1760 by thread T3:
    #0 -[__NSDictionaryM setObject:forKey:] <null> (CoreFoundation:arm64+0x19d84c)
    #1 __63-[AWSIoTMQTTClient publishData:qos:onTopic:retain:ackCallback:]_block_invoke <null> (AWSIoT:arm64+0x183468)
    #2 -[AWSMQTTSession publishDataAtLeastOnce:onTopic:retain:onMessageIdResolved:] <null> (AWSIoT:arm64+0x1e8444)
    #3 -[AWSIoTMQTTClient publishData:qos:onTopic:retain:ackCallback:] <null> (AWSIoT:arm64+0x183144)
    #4 -[AWSIoTMQTTClient publishData:qos:onTopic:ackCallback:] <null> (AWSIoT:arm64+0x182920)
    #5 -[AWSIoTMQTTClient publishString:qos:onTopic:ackCallback:] <null> (AWSIoT:arm64+0x182430)
    #6 -[AWSIoTDataManager publishString:onTopic:QoS:ackCallback:] <null> (AWSIoT:arm64+0xe83c)
    #7 closure #1 @Sendable 

  Previous modifying access of NSMutableDictionary at 0x0001074c1760 by thread T17:
    #0 -[__NSDictionaryM removeObjectForKey:] <null> (CoreFoundation:arm64+0x19d238)
    #1 -[AWSIoTMQTTClient session:newAckForMessageId:] <null> (AWSIoT:arm64+0x1891e4)
    #2 -[AWSMQTTSession handleSuback:] <null> (AWSIoT:arm64+0x1ec5f8)
    #3 -[AWSMQTTSession newMessage:] <null> (AWSIoT:arm64+0x1ebe30)
    #4 -[AWSMQTTSession decoder:newMessage:] <null> (AWSIoT:arm64+0x1eb868)
    #5 -[AWSMQTTDecoder stream:handleEvent:] <null> (AWSIoT:arm64+0x1e0c80)
    #6 _inputStreamCallbackFunc <null> (CoreFoundation:arm64+0x6834c)
    #7 __NSThread__start__ <null> (Foundation:arm64+0x76c27c)
  1. Verbose logs related to the library:
2025-01-22 09:50:04:480   [4384:63510] Websocket did open and is connected.
2025-01-22 09:50:04:480   [4384:63513] Started execution of Thread: [<AWSIoTStreamThread: 0x111d25d40>{number = 15, name = (null)}]
2025-01-22 09:50:04:480   [4384:63513] <<<AWSIoTStreamThread: 0x111d25d40>{number = 15, name = (null)}>> Initializing MQTTEncoder and MQTTDecoder streams
2025-01-22 09:50:04:480   [4384:63513] opening encoder stream.
2025-01-22 09:50:04:480   [4384:63513] opening decoder stream.
2025-01-22 09:50:04:480   [4384:63513] -[AWSMQTTEncoder stream:handleEvent:] [Line 58] EventCode:1, Thread: <AWSIoTStreamThread: 0x111d25d40>{number = 15, name = (null)}
2025-01-22 09:50:04:480   [4384:63513] -[AWSMQTTEncoder stream:handleEvent:] [Line 58] EventCode:4, Thread: <AWSIoTStreamThread: 0x111d25d40>{number = 15, name = (null)}
2025-01-22 09:50:04:480   [4384:63513] MQTTEncoderStatus = 0
2025-01-22 09:50:04:480   [4384:63513] -[AWSMQTTSession encoder:handleEvent:] [Line 336], eventCode: 0
2025-01-22 09:50:04:480   [4384:63513] MQTTSessionStatus = 0
2025-01-22 09:50:04:481   [4384:63513] sending 84 bytes
2025-01-22 09:50:04:481   [4384:63513] -[AWSMQTTDecoder stream:handleEvent:] [Line 63] EventCode:1, status:0, stream: <__NSCFInputStream: 0x111d25a70>, Thread: <AWSIoTStreamThread: 0x111d25d40>{number = 15, name = (null)}
2025-01-22 09:50:04:481   [4384:63478] [SR] NSStreamEventHasSpaceAvailable <__NSCFOutputStream: 0x111d03c30>
2025-01-22 09:50:04:715   [4384:63510] [SR] NSStreamEventHasBytesAvailable <__NSCFInputStream: 0x111d038d0>
2025-01-22 09:50:04:715   [4384:63510] [SR] Received message
2025-01-22 09:50:04:715   [4384:63510] [SR] using _delegateDispatchQueue.
2025-01-22 09:50:04:715   [4384:63498] Websocket didReceiveMessage: Received 4 bytes
2025-01-22 09:50:04:715   [4384:63513] -[AWSMQTTDecoder stream:handleEvent:] [Line 63] EventCode:2, status:1, stream: <__NSCFInputStream: 0x111d25a70>, Thread: <AWSIoTStreamThread: 0x111d25d40>{number = 15, name = (null)}
2025-01-22 09:50:04:715   [4384:63513] -[AWSMQTTSession decoder:newMessage:] [Line 388] messageType=2, status=1
2025-01-22 09:50:04:715   [4384:63513] MQTTSessionDelegate handleEvent: 0
2025-01-22 09:50:04:715   [4384:63513] MQTT session connected.
2025-01-22 09:50:04:715   [4384:63513] Auto-resubscribe is enabled. Resubscribing to topics.
2025-01-22 09:50:05:719   [4384:63513] ClockTick:1: nothing to republish
2025-01-22 09:50:05:719   [4384:63513] Connection Age: 1
2025-01-22 09:50:05:901   [4384:63465] Subscribing to topic $aws/things/*/shadow/get/accepted with messageCallback
2025-01-22 09:50:05:901   [4384:63465] messageId sending now 2
2025-01-22 09:50:05:901   [4384:63465] <<<NSThread: 0x10786b840>{number = 7, name = (null)}>>: MQTTSession.send msg to server
2025-01-22 09:50:05:901   [4384:63465] sending 64 bytes
2025-01-22 09:50:05:901   [4384:63465] Now subscribing w/ messageId: 2
2025-01-22 09:50:05:901   [4384:63474] [SR] NSStreamEventHasSpaceAvailable <__NSCFOutputStream: 0x111d03c30>
2025-01-22 09:50:05:980   [4384:63474] [SR] NSStreamEventHasBytesAvailable <__NSCFInputStream: 0x111d038d0>
2025-01-22 09:50:05:980   [4384:63474] [SR] Received message
2025-01-22 09:50:05:980   [4384:63474] [SR] using _delegateDispatchQueue.
2025-01-22 09:50:05:980   [4384:63510] Websocket didReceiveMessage: Received 5 bytes
2025-01-22 09:50:05:980   [4384:63513] -[AWSMQTTDecoder stream:handleEvent:] [Line 63] EventCode:2, status:1, stream: <__NSCFInputStream: 0x111d25a70>, Thread: <AWSIoTStreamThread: 0x111d25d40>{number = 15, name = (null)}
2025-01-22 09:50:05:980   [4384:63513] -[AWSMQTTSession decoder:newMessage:] [Line 388] messageType=9, status=2
2025-01-22 09:50:05:980   [4384:63513] MQTTSession- newMessage msg type is 9
2025-01-22 09:50:05:980   [4384:63513] -[AWSMQTTSession handleSuback:] [Line 471] 
2025-01-22 09:50:05:980   [4384:63513] Sub Ack messageId 2
2025-01-22 09:50:05:980   [4384:63513] MQTTSessionDelegate new ack for msgId: 2
2025-01-22 09:50:05:982   [4384:63478] Subscribing to topic $aws/things/*/shadow/update/documents with messageCallback
2025-01-22 09:50:05:982   [4384:63478] messageId sending now 3
2025-01-22 09:50:05:982   [4384:63478] <<<NSThread: 0x107873240>{number = 8, name = (null)}>>: MQTTSession.send msg to server
2025-01-22 09:50:05:982   [4384:63478] sending 68 bytes
2025-01-22 09:50:05:982   [4384:63478] Now subscribing w/ messageId: 3
2025-01-22 09:50:05:982   [4384:63474] [SR] NSStreamEventHasSpaceAvailable <__NSCFOutputStream: 0x111d03c30>
2025-01-22 09:50:06:053   [4384:63468] [SR] NSStreamEventHasBytesAvailable <__NSCFInputStream: 0x111d038d0>
2025-01-22 09:50:06:053   [4384:63468] [SR] Received message
2025-01-22 09:50:06:053   [4384:63468] [SR] using _delegateDispatchQueue.
2025-01-22 09:50:06:053   [4384:63474] Websocket didReceiveMessage: Received 5 bytes
2025-01-22 09:50:06:053   [4384:63513] -[AWSMQTTDecoder stream:handleEvent:] [Line 63] EventCode:2, status:1, stream: <__NSCFInputStream: 0x111d25a70>, Thread: <AWSIoTStreamThread: 0x111d25d40>{number = 15, name = (null)}
2025-01-22 09:50:06:053   [4384:63513] -[AWSMQTTSession decoder:newMessage:] [Line 388] messageType=9, status=2
2025-01-22 09:50:06:053   [4384:63513] MQTTSession- newMessage msg type is 9
2025-01-22 09:50:06:053   [4384:63513] -[AWSMQTTSession handleSuback:] [Line 471] 
2025-01-22 09:50:06:053   [4384:63513] Sub Ack messageId 3
2025-01-22 09:50:06:053   [4384:63513] MQTTSessionDelegate new ack for msgId: 3
2025-01-22 09:50:06:053   [4384:63474] <<<NSThread: 0x1078c20c0>{number = 16, name = (null)}>> MQTTEncoderStatus = 1
2025-01-22 09:50:06:053   [4384:63474] isReadyToPublish: 1
2025-01-22 09:50:06:053   [4384:63474] Publish message on topic: $aws/things/*/shadow/get, qos: 1, mssgId: 4, retain flag: false, dup flag: false
2025-01-22 09:50:06:053   [4384:63474] Published message 4 for QOS 1
2025-01-22 09:50:06:053   [4384:63474] <<<NSThread: 0x1078c20c0>{number = 16, name = (null)}>>: MQTTSession.send msg to server
2025-01-22 09:50:06:053   [4384:63474] sending 54 bytes
2025-01-22 09:50:06:053   [4384:63474] [SR] NSStreamEventHasSpaceAvailable <__NSCFOutputStream: 0x111d03c30>
2025-01-22 09:50:06:096   [4384:63478] [SR] NSStreamEventHasBytesAvailable <__NSCFInputStream: 0x111d038d0>
2025-01-22 09:50:06:096   [4384:63478] [SR] Received message
2025-01-22 09:50:06:096   [4384:63478] [SR] using _delegateDispatchQueue.
2025-01-22 09:50:06:096   [4384:63477] Websocket didReceiveMessage: Received 4 bytes
2025-01-22 09:50:06:096   [4384:63513] -[AWSMQTTDecoder stream:handleEvent:] [Line 63] EventCode:2, status:1, stream: <__NSCFInputStream: 0x111d25a70>, Thread: <AWSIoTStreamThread: 0x111d25d40>{number = 15, name = (null)}
2025-01-22 09:50:06:096   [4384:63513] -[AWSMQTTSession decoder:newMessage:] [Line 388] messageType=4, status=2
2025-01-22 09:50:06:096   [4384:63513] MQTTSession- newMessage msg type is 4
2025-01-22 09:50:06:096   [4384:63513] Pub Ack messageId 4
2025-01-22 09:50:06:096   [4384:63513] Removing msgID 4 from internal store for QOS1 guarantee
2025-01-22 09:50:06:096   [4384:63513] MQTTSessionDelegate new ack for msgId: 4
2025-01-22 09:50:06:096   [4384:63510] Subscribing to topic $aws/things/*/shadow/get/accepted with messageCallback
2025-01-22 09:50:06:096   [4384:63510] messageId sending now 5
2025-01-22 09:50:06:096   [4384:63510] <<<NSThread: 0x1078471c0>{number = 14, name = (null)}>>: MQTTSession.send msg to server
2025-01-22 09:50:06:096   [4384:63510] sending 64 bytes
2025-01-22 09:50:06:096   [4384:63510] Now subscribing w/ messageId: 5
2025-01-22 09:50:06:096   [4384:63468] [SR] NSStreamEventHasSpaceAvailable <__NSCFOutputStream: 0x111d03c30>
2025-01-22 09:50:06:146   [4384:63474] [SR] NSStreamEventHasBytesAvailable <__NSCFInputStream: 0x111d038d0>
2025-01-22 09:50:06:146   [4384:63474] [SR] Received message
2025-01-22 09:50:06:146   [4384:63474] [SR] using _delegateDispatchQueue.
2025-01-22 09:50:06:146   [4384:63468] Websocket didReceiveMessage: Received 2230 bytes
2025-01-22 09:50:06:146   [4384:63513] -[AWSMQTTDecoder stream:handleEvent:] [Line 63] EventCode:2, status:1, stream: <__NSCFInputStream: 0x111d25a70>, Thread: <AWSIoTStreamThread: 0x111d25d40>{number = 15, name = (null)}
2025-01-22 09:50:06:147   [4384:63513] -[AWSMQTTDecoder stream:handleEvent:] [Line 63] EventCode:2, status:3, stream: <__NSCFInputStream: 0x111d25a70>, Thread: <AWSIoTStreamThread: 0x111d25d40>{number = 15, name = (null)}
2025-01-22 09:50:06:147   [4384:63513] -[AWSMQTTDecoder stream:handleEvent:] [Line 63] EventCode:2, status:3, stream: <__NSCFInputStream: 0x111d25a70>, Thread: <AWSIoTStreamThread: 0x111d25d40>{number = 15, name = (null)}
2025-01-22 09:50:06:147   [4384:63513] -[AWSMQTTSession decoder:newMessage:] [Line 388] messageType=3, status=2
2025-01-22 09:50:06:147   [4384:63513] MQTTSession- newMessage msg type is 3
2025-01-22 09:50:06:147   [4384:63513] -[AWSMQTTSession handlePublish:] [Line 502] 
2025-01-22 09:50:06:147   [4384:63513] MQTTSessionDelegate newMessage: utput":,"version":387640,"timestamp":1737535806} onTopic: $aws/things/*/shadow/get/accepted
2025-01-22 09:50:06:147   [4384:63513] <<<AWSIoTStreamThread: 0x111d25d40>{number = 15, name = (null)}>>Topic: $aws/things/*/shadow/get/accepted is matched.
2025-01-22 09:50:06:147   [4384:63513] <<<AWSIoTStreamThread: 0x111d25d40>{number = 15, name = (null)}>>topicModel.callback.
2025-01-22 09:50:06:147   [4384:63513] <<<AWSIoTStreamThread: 0x111d25d40>{number = 15, name = (null)}>>: MQTTSession.send msg to server
2025-01-22 09:50:06:147   [4384:63513] sending 4 bytes
2025-01-22 09:50:06:147   [4384:63465] [SR] NSStreamEventHasSpaceAvailable <__NSCFOutputStream: 0x111d03c30>
2025-01-22 09:50:06:180   [4384:63477] [SR] NSStreamEventHasBytesAvailable <__NSCFInputStream: 0x111d038d0>
2025-01-22 09:50:06:180   [4384:63477] [SR] Received message
2025-01-22 09:50:06:180   [4384:63477] [SR] using _delegateDispatchQueue.
2025-01-22 09:50:06:180   [4384:63510] Websocket didReceiveMessage: Received 5 bytes
2025-01-22 09:50:06:180   [4384:63513] -[AWSMQTTDecoder stream:handleEvent:] [Line 63] EventCode:2, status:1, stream: <__NSCFInputStream: 0x111d25a70>, Thread: <AWSIoTStreamThread: 0x111d25d40>{number = 15, name = (null)}
2025-01-22 09:50:06:180   [4384:63513] -[AWSMQTTSession decoder:newMessage:] [Line 388] messageType=9, status=2
2025-01-22 09:50:06:180   [4384:63513] MQTTSession- newMessage msg type is 9
2025-01-22 09:50:06:180   [4384:63513] -[AWSMQTTSession handleSuback:] [Line 471] 
2025-01-22 09:50:06:180   [4384:63513] Sub Ack messageId 5
2025-01-22 09:50:06:180   [4384:63513] MQTTSessionDelegate new ack for msgId: 5
2025-01-22 09:50:06:181   [4384:63468] Subscribing to topic $aws/things/*/shadow/update/documents with messageCallback
2025-01-22 09:50:06:181   [4384:63468] messageId sending now 6
2025-01-22 09:50:06:181   [4384:63468] <<<NSThread: 0x10784d640>{number = 9, name = (null)}>>: MQTTSession.send msg to server
2025-01-22 09:50:06:181   [4384:63468] sending 68 bytes
2025-01-22 09:50:06:181   [4384:63468] Now subscribing w/ messageId: 6
2025-01-22 09:50:06:181   [4384:63510] [SR] NSStreamEventHasSpaceAvailable <__NSCFOutputStream: 0x111d03c30>
2025-01-22 09:50:06:287   [4384:63469] [SR] NSStreamEventHasBytesAvailable <__NSCFInputStream: 0x111d038d0>
2025-01-22 09:50:06:287   [4384:63469] [SR] Received message
2025-01-22 09:50:06:287   [4384:63469] [SR] using _delegateDispatchQueue.
2025-01-22 09:50:06:287   [4384:63510] Websocket didReceiveMessage: Received 5 bytes
2025-01-22 09:50:06:287   [4384:63513] -[AWSMQTTDecoder stream:handleEvent:] [Line 63] EventCode:2, status:1, stream: <__NSCFInputStream: 0x111d25a70>, Thread: <AWSIoTStreamThread: 0x111d25d40>{number = 15, name = (null)}
2025-01-22 09:50:06:287   [4384:63513] -[AWSMQTTSession decoder:newMessage:] [Line 388] messageType=9, status=2
2025-01-22 09:50:06:287   [4384:63513] MQTTSession- newMessage msg type is 9
2025-01-22 09:50:06:287   [4384:63513] -[AWSMQTTSession handleSuback:] [Line 471] 
2025-01-22 09:50:06:287   [4384:63513] Sub Ack messageId 6
2025-01-22 09:50:06:287   [4384:63513] MQTTSessionDelegate new ack for msgId: 6
2025-01-22 09:50:06:287   [4384:63477] <<<NSThread: 0x10786e980>{number = 10, name = (null)}>> MQTTEncoderStatus = 1
2025-01-22 09:50:06:287   [4384:63477] isReadyToPublish: 1
2025-01-22 09:50:06:287   [4384:63477] Publish message on topic: $aws/things/*/shadow/get, qos: 1, mssgId: 7, retain flag: false, dup flag: false
2025-01-22 09:50:06:287   [4384:63477] Published message 7 for QOS 1
2025-01-22 09:50:06:288   [4384:63477] <<<NSThread: 0x10786e980>{number = 10, name = (null)}>>: MQTTSession.send msg to server
2025-01-22 09:50:06:288   [4384:63477] sending 54 bytes
2025-01-22 09:50:06:288   [4384:63478] [SR] NSStreamEventHasSpaceAvailable <__NSCFOutputStream: 0x111d03c30>
2025-01-22 09:50:06:335   [4384:63463] [SR] NSStreamEventHasBytesAvailable <__NSCFInputStream: 0x111d038d0>
2025-01-22 09:50:06:335   [4384:63463] [SR] Received message
2025-01-22 09:50:06:335   [4384:63463] [SR] using _delegateDispatchQueue.
2025-01-22 09:50:06:335   [4384:63477] Websocket didReceiveMessage: Received 4 bytes
2025-01-22 09:50:06:335   [4384:63513] -[AWSMQTTDecoder stream:handleEvent:] [Line 63] EventCode:2, status:1, stream: <__NSCFInputStream: 0x111d25a70>, Thread: <AWSIoTStreamThread: 0x111d25d40>{number = 15, name = (null)}
2025-01-22 09:50:06:335   [4384:63513] -[AWSMQTTSession decoder:newMessage:] [Line 388] messageType=4, status=2
2025-01-22 09:50:06:335   [4384:63513] MQTTSession- newMessage msg type is 4
2025-01-22 09:50:06:335   [4384:63513] Pub Ack messageId 7
2025-01-22 09:50:06:335   [4384:63513] Removing msgID 7 from internal store for QOS1 guarantee
2025-01-22 09:50:06:335   [4384:63513] MQTTSessionDelegate new ack for msgId: 7
2025-01-22 09:50:06:417   [4384:63468] [SR] NSStreamEventHasBytesAvailable <__NSCFInputStream: 0x111d038d0>
2025-01-22 09:50:06:417   [4384:63468] [SR] Received message
2025-01-22 09:50:06:417   [4384:63468] [SR] using _delegateDispatchQueue.
2025-01-22 09:50:06:417   [4384:63465] Websocket didReceiveMessage: Received 1874 bytes
2025-01-22 09:50:06:417   [4384:63513] -[AWSMQTTDecoder stream:handleEvent:] [Line 63] EventCode:2, status:1, stream: <__NSCFInputStream: 0x111d25a70>, Thread: <AWSIoTStreamThread: 0x111d25d40>{number = 15, name = (null)}
2025-01-22 09:50:06:417   [4384:63513] -[AWSMQTTDecoder stream:handleEvent:] [Line 63] EventCode:2, status:3, stream: <__NSCFInputStream: 0x111d25a70>, Thread: <AWSIoTStreamThread: 0x111d25d40>{number = 15, name = (null)}
2025-01-22 09:50:06:417   [4384:63513] -[AWSMQTTDecoder stream:handleEvent:] [Line 63] EventCode:2, status:3, stream: <__NSCFInputStream: 0x111d25a70>, Thread: <AWSIoTStreamThread: 0x111d25d40>{number = 15, name = (null)}
2025-01-22 09:50:06:417   [4384:63513] -[AWSMQTTSession decoder:newMessage:] [Line 388] messageType=3, status=2
2025-01-22 09:50:06:417   [4384:63513] MQTTSession- newMessage msg type is 3

matildemarcelletti23 avatar Jan 22 '25 08:01 matildemarcelletti23

Thanks for the info. At this moment we are unable to reproduce this issue in a local isolated environment. That being said, we will still investigate and validate if we can find a root cause.

harsh62 avatar Jan 28 '25 17:01 harsh62

I have never seen this happen on the simulator or on my device. But I have at least 10 reported crashes from users in the last month that are all related to this issue.

Is the temporary fix posted by @MatildeDevq a viable solution for now? I may need to make the same change myself if an official fix isn't on the way

tylerjames avatar Feb 28 '25 04:02 tylerjames

Any hope of this change making it into a release soon?

I'm seeing this same crash but I'd rather not have to rebuild the library to apply this one fix

tylerjames avatar Mar 05 '25 15:03 tylerjames

@tylerjames Unfortunately we have not had the bandwidth to look at the workaround solution yet to provide a full fix. The fact that noone can reproduce this locally and that the crash is rare makes it difficult to test. For you, can you try the workaround to see if that improves your crash numbers and if it does, please let us know! That will give us valuable data.

vincetran avatar Mar 05 '25 18:03 vincetran

@MatildeDevq have you applied this fix? And has it resolved the issues?

tylerjames avatar Mar 05 '25 20:03 tylerjames

@tylerjames yes I applied the fix I mentioned above and I no longer had any crashes or race conditions

matildemarcelletti23 avatar Mar 05 '25 20:03 matildemarcelletti23

@MatildeDevq

Nice. Was the process for rebuilding the library as tedious as it sounds?

tylerjames avatar Mar 05 '25 20:03 tylerjames

@tylerjames I meant that I applied the temporary fix I mentioned in the fork not the permanent fix that changes the concurrency handling on the library

matildemarcelletti23 avatar Mar 05 '25 20:03 matildemarcelletti23

Ah. Are you using the library as an SPM package? I think there's a different procedure when making changes to the SPM package

https://github.com/aws-amplify/aws-sdk-ios-spm

tylerjames avatar Mar 05 '25 20:03 tylerjames

@tylerjames I used pod and referenced the specific branch of the fork like this: pod 'AWSIoT', :git => 'https://github.com/MatildeDevq/aws-sdk-ios.git', :branch => 'fix/iot-race-conditions'

matildemarcelletti23 avatar Mar 05 '25 20:03 matildemarcelletti23