0

One of the users of my app experiences a crash every time an HTTP request is made (to the API). This is the crash trace:

Incident Identifier: 512C99DF-D432-4BAC-96DF-B32561A51C9B
CrashReporter Key:   cdee4dd4d00f061439ba8ee6e2fdf4d5a9c4e889
Hardware Model:      iPhone5,3
Process:             myapp [312]
Path:                /private/var/mobile/Containers/Bundle/Application/42EA0E64-28BB-48D0-9CDF-6F58F1823BDF/myapp.app/myapp
Identifier:          com.myapp.myapp
Version:             3 (0.1.2)
Code Type:           ARM (Native)
Parent Process:      launchd [1]

Date/Time:           2017-01-18 21:30:47.47 -0500
Launch Time:         2017-01-18 21:30:41.41 -0500
OS Version:          iOS 9.1 (13B143)
Report Version:      105

Exception Type:  EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note:  EXC_CORPSE_NOTIFY
Triggered by Thread:  0

Filtered syslog:
None found

Last Exception Backtrace:
(0x24dc5856 0x3673adfa 0x24d58bda 0xfe438 0x29188ae8 0x29188c34 0x295ccf7c 0x290b18d8 0x28fda85c 0x28fda68a 0x290b10cc 0x2880a85a 0x2880a6aa 0x2e897586 0x25e85340 0x24d76b54 0x24d88f76 0x24d8868a 0x24d86a9c 0x24cd90d4 0x24cd8ec8 0x2e04eaf4 0x28f622d8 0xa0288 0x36e8886e)

Global Trace Buffer (reverse chronological seconds):
2.392224     CFNetwork                 0x00000000245e4a91 TCP Conn 0x15d78310 SSL Handshake DONE
2.598566     CFNetwork                 0x00000000245e49cb TCP Conn 0x15d78310 starting SSL negotiation
2.599330     CFNetwork                 0x000000002466479d TCP Conn 0x15d78310 complete. fd: 6, err: 0
2.600883     CFNetwork                 0x000000002466589f TCP Conn 0x15d78310 event 1. err: 0
3.702969     CFNetwork                 0x000000002466591d TCP Conn 0x15d78310 started
3.710171     CFNetwork                 0x00000000246a640f Creating default cookie storage with default identifier
3.710171     CFNetwork                 0x00000000246a63eb Faulting in CFHTTPCookieStorage singleton
3.710171     CFNetwork                 0x00000000246e878b Faulting in NSHTTPCookieStorage singleton
3.714408     CFNetwork                 0x000000002463e141 NSURLSessionTask finished with error - code: -1022
4.907331     libsystem_trace.dylib     0x00000000370086f9 dyld_image_header_containing_address(0x15e505e9) failed

However the app works for all other users and I know the API endpoint is fully reachable. This is also a React Native app, don't know if that's relevant to this, but here's the code that makes the request:

export default function api(apiName, paramsObj) {
  return new Promise((resolve, reject) => {
    let ip = 'xxx.xxx.xx.xxx';
    fetch(`http://${ip}/api/${apiName}`, {
      method: 'POST',
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json',
      },
      body: paramsObj ? JSON.stringify(paramsObj) : null
    })
    .then(response => resolve(response.json()))
    .catch(error => reject(error));
  });
}

Any idea what could be causing this crash?

EDIT

This is an example of the API's JSON response:

[{"id":"584b7fe3e1e982176d5a5b3c","name":"My University","unlocked":true,"totalUsers":1200,"minimumUsers":1000}]

EDIT 2

Here is a screenshot of the symbolicated crash report from Xcode (the app name is blocked out):

Symbolicated crash report from Xcode

EDIT 3

After further testing and debugging I determined that the issue also sometimes occurs on iPhone 5s running 8.x. Regardless, I saw this answer to a different question, and when I added these lines to the entry point of the app, it actually fixed the problem only when I click "Debug JS Remotely" in the React Native developer menu.

const _XHR = GLOBAL.originalXMLHttpRequest ?  
    GLOBAL.originalXMLHttpRequest :           
    GLOBAL.XMLHttpRequest                     

XMLHttpRequest = _XHR

So essentially with these above lines, when the simulator (iPhone 4s, iOS 9.3) is connected to the React Native Chrome debugger the problem stops and the list is populated (no out-of-bounds error). However if I disconnect the simulator from the debugger OR if I run the app in release mode, the error persists.

Community
  • 1
  • 1
Leopold Joy
  • 4,524
  • 4
  • 28
  • 37

2 Answers2

1

An object of type RTCPicker (subclass of UIPickerView) is trying to access an item from an Array that doesn't exist. Something like you have 5 items in the array and try to access the 6th item.

This is indicated by the top frame showing that the call stack is throwing an exception and the 3rd frame trying to access in item from an NSArray at a specific index.

As exceptions are fatals, this will crash the app.

Kerni
  • 15,241
  • 5
  • 36
  • 57
  • Thank you!! Basically the `RTCPicker` is populated by a API call which 100% of the time returns data for the picker (the JSON array returned is never empty). On all 64-bit devices this crash does not occur and the API successfully returns the result. However it always crashes and fails to populate the array on all 32-bit devices (iPhone 4S and earlier), any idea why this would happen? – Leopold Joy Jan 23 '17 at 09:46
  • @UnknownUser probably no way to tell without debugging on the affected device. Can you reproduce the problem in the simulator? – Pekka Jan 23 '17 at 09:47
  • @Pekka웃 Yes, I am able to reproduce the problem on an iPhone 4S in the simulator. – Leopold Joy Jan 23 '17 at 09:48
  • @UnknownUser I'd try and debug my way to the root cause, possibly starting with that API call and seeing why the results are not coming through – Pekka Jan 23 '17 at 09:49
  • @Pekka웃 Thanks! I have been trying to debug it, I believe what @SeanLintern88 said about Int64s crashing on a 32-bit iPhone could be the problem, since the API returns ints that are from `Node.js/MongoDB` and I believe may be Int64. Do you know how I could try to convert Int64 to Int32 to see if that helps? I assume it would have to be done on the server-side. – Leopold Joy Jan 23 '17 at 09:54
  • It would be news to me that common JSON has even a *concept* of int32 or int64... you'd probably have to look at how whatever you're using to fetch and parse the JSON handles numbers. Are you really sure this is the actual issue? Kerni's answer seems to be giving a plausible reason for the crash itself, so now it's time to look for how it comes about. Can you not go to where the JSON output is handled, and see what your code is doing with it, whether the appropriate elements are created, etc.? – Pekka Jan 23 '17 at 09:57
  • I managed to get the out of bounds error to stop **only** when the app is connected to the `React Native` debugging server (see edit). Any idea why these lines fix the problem or how I can make it work when it's not connected to the debugger? – Leopold Joy Jan 25 '17 at 03:17
0

The -1022 error indicates that you're trying to fetch from an http server. You need to move to https or adjust your app's entitlements to allow cleartext loads.

My guess is that the request is failing because of that, and you're failing to detect the empty response correctly and trying to parse it as JSON, then crashing, but without a decoded backtrace, it is impossible to say for sure.

dgatwood
  • 10,129
  • 1
  • 28
  • 49
  • Thanks! Any idea why it would only happen on old 32-bit iPhones (5 and below) if it's an `http` vs `https` type of problem? – Leopold Joy Jan 21 '17 at 06:37
  • 1
    No idea. Might be a difference in behavior in how some method handles an empty string. Either way, decode the backtrace first, and then the problem will probably be obvious. – dgatwood Jan 21 '17 at 17:56
  • I added a screenshot of the symbolicated version of the crash log, any idea what the problem could be? Thanks!! – Leopold Joy Jan 23 '17 at 08:51
  • The React picker view is trying to dereference an out-of-bounds index in an array, and NSArray throws an exception when you do so. Mind you, I can't tell you *why* that's happening. It could be: A. a race condition causing the backing store to change between when you try to select a particular row, B. the array being empty because of your load failing, C. a bug caused by performing operations on UI objects from a non-main thread, or possibly something else entirely, but that's where you should be looking. – dgatwood Jan 23 '17 at 09:06
  • Thank you!! Basically the `RTCPicker` is populated by a API call which 100% of the time returns data for the picker (the JSON array returned is never empty). On all 64-bit devices this crash does not occur and the API successfully returns the result. However it always crashes and fails to populate the array on all 32-bit devices (iPhone 4S and earlier), any idea why this would happen? – Leopold Joy Jan 23 '17 at 09:47
  • I managed to get the out of bounds error to stop **only** when the app is connected to the `React Native` debugging server (see edit). Any idea why these lines fix the problem or how I can make it work when it's not connected to the debugger? – Leopold Joy Jan 25 '17 at 03:17