进行 API 调用时,应用程序总是崩溃

Posted

技术标签:

【中文标题】进行 API 调用时,应用程序总是崩溃【英文标题】:App always crashes when API call is made 【发布时间】:2017-01-19 07:41:41 【问题描述】:

每次(向 API)发出 HTTP 请求时,我的应用程序的一个用户都会遇到崩溃。这是崩溃跟踪:

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

但是,该应用适用于所有其他用户,并且我知道 API 端点是完全可访问的。这也是一个React Native 应用程序,不知道这是否与此相关,但这是发出请求的代码:

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));
  );

知道是什么导致了这次崩溃吗?

编辑

这是 API 的 JSON 响应示例:

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

编辑 2

这是来自 Xcode 的符号化崩溃报告的屏幕截图(应用名称被屏蔽):

编辑 3

经过进一步测试和调试,我确定问题也有时出现在运行 8.x 的 iPhone 5s 上。无论如何,我看到this answer 指向另一个问题,当我将这些行添加到应用程序的入口点时,它实际上解决了问题当我单击@中的“远程调试 JS”时987654328@开发者菜单。

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

XMLHttpRequest = _XHR

因此,基本上通过上述这些行,当模拟器(iPhone 4s,iOS 9.3)连接到 React Native Chrome 调试器时,问题停止并且列表被填充(没有越界错误)。但是,如果我断开模拟器与调试器的连接,或者如果我在 release 模式下运行应用程序,错误仍然存​​在。

【问题讨论】:

你也应该显示相关代码。 代码看起来很正常。但是 API 的响应是什么?响应是否是格式错误的 JSON? 您需要对崩溃报告进行符号化,尤其是 Last Exception Backtrace 需要进行符号化,因为它可以显示代码中的问题所在。 这种情况下接收的设备是不是64位的iphone 5?可能是您的 API 响应试图转换为 Int64 吗?这会使 iphone 5 及更低版本崩溃? 我相信 5c 是 32 位的 【参考方案1】:

RTCPicker 类型的对象(UIPickerView 的子类)正在尝试访问不存在的数组中的项目。就像您在数组中有 5 个项目并尝试访问第 6 个项目。

这由显示调用堆栈正在抛出异常的顶部框架以及尝试从特定索引处的 NSArray 访问项目的第 3 帧指示。

由于异常是致命的,这将使应用程序崩溃。

【讨论】:

谢谢!!基本上,RTCPicker 由 API 调用填充,该调用 100% 的时间为选择器返回数据(返回的 JSON 数组永远不会为空)。在所有 64 位设备上都不会发生这种崩溃,并且 API 会成功返回结果。但是它总是崩溃并且无法在所有 32 位设备(iPhone 4S 和更早版本)上填充阵列,知道为什么会发生这种情况吗? @UnknownUser 可能无法在受影响的设备上进行调试。你能在模拟器中重现这个问题吗? @Pekka웃 是的,我可以在模拟器中重现 iPhone 4S 上的问题。 @UnknownUser 我会尝试调试我的方法来找出根本原因,可能从那个 API 调用开始,看看为什么结果没有通过 @Pekka웃 谢谢!我一直在尝试调试它,我相信@SeanLintern88 关于 Int64s 在 32 位 iPhone 上崩溃的说法可能是问题所在,因为 API 返回来自Node.js/MongoDB 的整数,我相信可能是 Int64。您知道我如何尝试将 Int64 转换为 Int32 以查看是否有帮助吗?我认为它必须在服务器端完成。【参考方案2】:

-1022 错误表明您正在尝试从 http 服务器获取。您需要迁移到 https 或调整应用的权利以允许明文加载。

我的猜测是请求因此失败,并且您无法正确检测空响应并尝试将其解析为 JSON,然后崩溃,但没有解码的回溯,无法确定.

【讨论】:

谢谢!知道如果这是httphttps 类型的问题,为什么它只会发生在旧的 32 位 iPhone(5 及以下)上? 不知道。某些方法处理空字符串的方式可能有所不同。无论哪种方式,先解码回溯,然后问题可能会很明显。 我添加了崩溃日志的符号版本的屏幕截图,知道问题可能是什么吗?谢谢!! React 选择器视图试图取消引用数组中的越界索引,当你这样做时 NSArray 会抛出异常。请注意,我无法告诉您为什么会发生这种情况。它可能是:A. 竞争条件导致后备存储在您尝试选择特定行时发生变化,B. 由于加载失败,数组为空,C. 对来自 a 的 UI 对象执行操作导致的错误非主线程,或者可能完全是其他东西,但那是你应该寻找的地方。 谢谢!!基本上,RTCPicker 由 API 调用填充,该调用 100% 的时间为选择器返回数据(返回的 JSON 数组永远不会为空)。在所有 64 位设备上都不会发生这种崩溃,并且 API 成功返回了结果。但是它总是崩溃并且无法在所有 32 位设备(iPhone 4S 和更早版本)上填充阵列,知道为什么会发生这种情况吗?

以上是关于进行 API 调用时,应用程序总是崩溃的主要内容,如果未能解决你的问题,请参考以下文章

Android 9 (API 28) 活动在启动时崩溃 (setContentView)

C++ 程序在执行 std::string 分配时总是崩溃

当我在 FutureBuilder 中调用 ListView.builder 时,总是崩溃

OpenGL:随机调用 OpenGL 函数时崩溃

对“xxx”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们。 错误解决一例。(代码片段

我的网站总是崩溃 IE,无法调试