ios - PJSIP : Crash on pj_sockaddr_get_port when moving iOS app to background and then to foreground

标签 ios iphone voip pjsip

我有一个使用 PJSIP v2.3.0 的 iOS VOIP 应用程序。

在 iOS 11 发布后,我看到了很多崩溃的例子。我将 fabric (crashlytics) 与我的应用程序集成在一起,这是崩溃线程的回溯。

Crashed: Thread
0  libsystem_kernel.dylib         0x186819348 __pthread_kill + 8
1  libsystem_pthread.dylib        0x18692d354 pthread_kill$VARIANT$mp + 396
2  libsystem_c.dylib              0x186788fd8 abort + 140
3  libsystem_c.dylib              0x18675cabc basename_r + 314
4  MyApp                          0x101a2ab58 pj_sockaddr_get_port + 10115892
5  MyApp                          0x101a24e28 udp_on_read_complete + 10092036
6  MyApp                          0x1019bba74 ioqueue_dispatch_read_event + 9661008
7  MyApp                          0x1019bd1f0 pj_ioqueue_poll + 9667020
8  MyApp                          0x101a08788 pjsip_endpt_handle_events2 + 9975652
9  MyApp                          0x1019df334 worker_thread + 9806608
10 MyApp                          0x1019cf274 thread_main + 9740880
11 libsystem_pthread.dylib        0x18692c32c _pthread_body + 308
12 libsystem_pthread.dylib        0x18692c1f8 _pthread_body + 310
13 libsystem_pthread.dylib        0x18692ac38 thread_start + 4

线程因 pj_sockaddr_get_port 上的断言而崩溃

PJ_ASSERT_RETURN(a->addr.sa_family == PJ_AF_INET ||
             a->addr.sa_family == PJ_AF_INET6, (pj_uint16_t)0xFFFF);

注意:PJ_ENABLE_EXTRA_CHECK 为我的应用程序定义为 0,因此 PJ_ASSERT_RETURN 在这里只是 PJ_ASSERT。

导致这次崩溃的 PJSIP 日志讲述了一些有趣的事情。该应用程序已后台运行,并且已注销。当应用程序在几分钟后被带到前台时,它会尝试注册。

我看到了以下警告消息,同时 crashlytics 报告了上述带有回溯的崩溃。

2017-09-28 21:00:11 TID=50691 [pjsua] Log Level-1 : 16:00:11.267     ioq_select  Error replacing socket: Invalid argument
2017-09-28 21:00:11 TID=50691 [pjsua] Log Level-1 : 16:00:11.267     udp0x10de7f3a0  Warning: pj_ioqueue_recvfrom: [err 120009] Bad file descriptor
2017-09-28 21:00:11 TID=50691 [pjsua] Log Level-1 : 16:00:11.267     udp0x10de7f3a0  Warning: pj_ioqueue_recvfrom: [err 120009] Bad file descriptor
.
.
.
2017-09-28 21:00:18 TID=50691 [pjsua] Log Level-1 : 16:00:15.256     udp0x10de7f3a0  Warning: pj_ioqueue_recvfrom: [err 120057] Socket is not connected
2017-09-28 21:00:18 TID=50691 [pjsua] Log Level-1 : 16:00:15.256     udp0x10de7f3a0  Warning: pj_ioqueue_recvfrom: [err 120057] Socket is not connected
2017-09-28 21:00:18 TID=50691 [pjsua] Log Level-1 : 16:00:15.256     udp0x10de7f3a0  Warning: pj_ioqueue_recvfrom: [err 120057] Socket is not connected
.
.
.
2017-09-28 21:00:18 TID=50691 [pjsua] Log Level-1 : 16:00:18.262 udp0x10de7f3a0  Warning: pj_ioqueue_recvfrom: [err 120038] Socket operation on non-socket
2017-09-28 21:00:18 TID=50691 [pjsua] Log Level-1 : 16:00:18.262 udp0x10de7f3a0  Warning: pj_ioqueue_recvfrom: [err 120038] Socket operation on non-socket
2017-09-28 21:00:18 TID=50691 [pjsua] Log Level-1 : 16:00:18.262 udp0x10de7f3a0  Warning: pj_ioqueue_recvfrom: [err 120038] Socket operation on non-socket

根据我的理解,这些警告消息的出现是由于 udp_on_read_complete 内部的旋转循环。 iOS 可以重新声明 pjsip 尝试使用的套接字吗?

有人遇到过这个崩溃吗?欢迎任何类型的指示/指南。

最佳答案

我所做的修复是在 replace_udp_sock() 失败时简单地从 pjlib/src/pj/ioqueue_common_abs.c 中的 ioqueue_dispatch_read_event 方法返回。发生崩溃是因为忽略了错误并且使用错误的套接字调用了 on_read_complete。

我所做的改变:

rc = replace_udp_sock(h);
if (rc != PJ_SUCCESS) {
  PJ_LOG(3, (THIS_FILE, "UDP socket replacement failed with error status %d", rc));
  if (has_lock) {
      pj_ioqueue_unlock_key(h);
  }
  return;
}

如果这能解决您的问题,请告诉我。

关于ios - PJSIP : Crash on pj_sockaddr_get_port when moving iOS app to background and then to foreground,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46533888/

相关文章:

ios - Swift 3.0 TableView 单元格按钮

iphone - setNavigationBarHidden :NO Not Working after removeFromSuperview

facebook - 使用 CloudMade 和 Facebook iOs SDK 时出现重复符号 _OBJC_METACLASS_$_SBJSON

ios - PushKit 框架,它是如何工作的?

ios - phonegap ios 的示例 config.xml

iphone - 如何使用 Quartz Framework 绘制图形

ios - 在 iOS 中从字符串转换日期?

iphone - iOS5 NSManagedObjectContext 并发类型以及它们是如何使用的?

networking - 为什么RTP使用UDP而不是TCP?

algorithm - RTP:推荐策略以实现流畅的音频流