Skip to content
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

AWSPinpointSessionClient blocks main thread #614

Closed
jberkel opened this issue Mar 15, 2017 · 10 comments
Closed

AWSPinpointSessionClient blocks main thread #614

jberkel opened this issue Mar 15, 2017 · 10 comments
Labels
bug Something isn't working investigating This issue is being investigated

Comments

@jberkel
Copy link

jberkel commented Mar 15, 2017

To help us solve your problem better, please answer the following list of questions.

  • What service are you using?

AWSPinPoint

  • In what version of SDK are you facing the problem?

2.5.2

  • Is the issue limited to Simulators / Actual Devices?

Devices

  • Can your problem be resolved if you bump to a higher version of SDK?

No

  • Is this problem related to specific iOS version?

No

  • How are you consuming the SDK? CocoaPods / Carthage / Prebuilt frameworks?

CocoaPods

  • Can you give us steps to reproduce with a minimal, complete, and verifiable example? Please include any specific network conditions that might be required to reproduce the problem.

I use AWSPinpointAnalyticsClient in my app to track some events, using the default configuration (5 sec session timeout).

When my application goes into background state I noticed a couple of warnings in the console:

Mar 15 14:44:40 iPhone moti[765] <Warning>: Warning: A long-running operation is being executed on the main thread.
     Break on awsbf_warnBlockingOperationOnMainThread() to debug.

Followed (occasionally) by the process getting killed by the watchdog:

Exception Type:  00000020
Exception Codes: 0x000000008badf00d
Exception Note:  SIMULATED (this is NOT a crash)
Highlighted by Thread:  2

Application Specific Information:
<BKNewProcess: 0x15d6efd0; com.zegoggles.moti; pid: 736; hostpid: -1> has active assertions beyond permitted time: 
{(
    <BKProcessAssertion: 0x15e5bfb0> id: 736-966B0D80-6F3B-4522-B114-6D36360D9DA0 name: com.amazonaws.AWSPinpointSessionBackgroundTask process: <BKNewProcess: 0x15d6efd0; com.zegoggles.moti; pid: 736; hostpid: -1> permittedBackgroundDuration: 180.000000 reason: finishTask owner pid:736 preventSuspend  preventIdleSleep  preventSuspendOnSleep 
)}

I attach the debugger as hinted in the log message:

(lldb) b awsbf_warnBlockingOperationOnMainThread
Breakpoint 2: where = AWSCore`awsbf_warnBlockingOperationOnMainThread, address = 0x003b7b00

Getting the following backtrace:

(lldb) bt
* thread #1: tid = 0x33700, 0x003b7b00 AWSCore`awsbf_warnBlockingOperationOnMainThread, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1
  * frame #0: 0x003b7b00 AWSCore`awsbf_warnBlockingOperationOnMainThread
    frame #1: 0x003ba0fc AWSCore`-[AWSTask waitUntilFinished] + 132
    frame #2: 0x00505930 AWSPinpoint`-[AWSPinpointSessionClient endCurrentSessionWithBlock:] + 252
    frame #3: 0x0050582a AWSPinpoint`-[AWSPinpointSessionClient endCurrentSessionTimeoutWithTimer:] + 100
    frame #4: 0x240d2654 Foundation`__NSFireTimer + 64
    frame #5: 0x2386a58e CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 14
    frame #6: 0x2386a1c0 CoreFoundation`__CFRunLoopDoTimer + 936
    frame #7: 0x2386800c CoreFoundation`__CFRunLoopRun + 1484
    frame #8: 0x237b7228 CoreFoundation`CFRunLoopRunSpecific + 520
    frame #9: 0x237b7014 CoreFoundation`CFRunLoopRunInMode + 108
    frame #10: 0x24da7ac8 GraphicsServices`GSEventRunModal + 160
    frame #11: 0x27e8b188 UIKit`UIApplicationMain + 144
    frame #12: 0x000337dc moti`_mh_execute_header + 26588
    frame #13: 0x2345f872 libdyld.dylib`start 

After checking the code it looks like NSTimer fires after the prefined timeout without passing a block in the userInfo dictionary:

https://github.com/aws/aws-sdk-ios/blob/master/AWSPinpoint/AWSPinpointSessionClient.m#L122

It ends up calling endCurrentSessionTimeoutWithTimer:(NSTimer*), followed by endCurrentSessionWithBlock:block (with the block still being nil).

In endCurrentSessionWithBlock: the application finally hangs in waitUntilFinished on the main thread.

@jberkel
Copy link
Author

jberkel commented Mar 30, 2017

Anyone out there? It's quite a serious problem and prevents the use of Pinpoint in production.

@rohandubal
Copy link
Contributor

Hi,

Thanks for reporting this. I will reach out to the service team and revert.

Thanks,
Rohan

@yinglin83
Copy link

@jberkel did you figure a solution to this problem? Our app is already in production. now it gets killed by system all the time due to this bug.

@jberkel
Copy link
Author

jberkel commented May 9, 2017

@yinglin83 Well I debugged the app and identified the problem (see above), a fix is probably not too complicated but I have other priorities right now. very likely won't use the service anyway, given the low quality of the code and the slow response times.

@yinglin83
Copy link

@jberkel Thanks for pointing that out. I agreed that they need to improve the quality of pinpoint code before asking everyone to jump onboard. I wonder how many poor mobile startups out there having this code in production. This issue has huge impact on our app store ranking. This update drop our ratings from 5 stars to 3.5 stars. This is SERIOUS!

@cheruvian
Copy link

Great catch @jberkel and appreciate the thorough write up and debug.

Looks like we not only have some work to do in the Pinpoint session client but also with our GitHub issue response times.

We apologize for the lack of responsiveness along with any problems this may have caused.

You should expect a fix shortly and please know that we value your continued patience as we actively dive in and resolve this issue.

@cheruvian cheruvian added bug Something isn't working investigating This issue is being investigated labels May 24, 2017
@cheruvian cheruvian self-assigned this May 24, 2017
@cheruvian
Copy link

Ok looks like the change is all approved and will be released shortly.

@cheruvian
Copy link

Unfortunately looks like the change broke existing functional tests and is pending further work.

@decentralisedkev
Copy link

A band-aid solution would be to find the waitUntilFinsihed function, and when it checks if the thread is running on the main, put it in the back, So:

  • (void)waitUntilFinished {

    if ([NSThread isMainThread]) {
    [self warnOperationOnMainThread];
    NSLog(@"Moving to background thread");
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);
    dispatch_async(queue, ^{

          @synchronized(self.lock) {
              if (self.completed) {
                  return;
              }
              [self.condition lock];
          }
          // TODO: (nlutsenko) Restructure this to use Bolts-Swift thread access synchronization architecture
          // In the meantime, it's absolutely safe to get `_completed` aka an ivar, as long as it's a `BOOL` aka less than word size.
          while (!_completed) {
              [self.condition wait];
          }
          [self.condition unlock];
          
          
       });
    

    } else {

      @synchronized(self.lock) {
          if (self.completed) {
              return;
          }
          [self.condition lock];
      }
      // TODO: (nlutsenko) Restructure this to use Bolts-Swift thread access synchronization architecture
      // In the meantime, it's absolutely safe to get `_completed` aka an ivar, as long as it's a `BOOL` aka less than word size.
      while (!_completed) {
          [self.condition wait];
      }
      [self.condition unlock];
    

    }

}

This should help those looking for a quick fix, just comment out the [self warnOperationOnMainThread]; part to stop it showing up now

@lexmakali
Copy link
Contributor

We have fixed it in 2.5.9

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working investigating This issue is being investigated
Projects
None yet
Development

No branches or pull requests

6 participants