You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS15下多线程并行发起网络请求时Curl ossl_connect_common函数崩溃

崩溃基础信息

调用栈

0 libsystem_pthread.dylib
0x5948 pthread_rwlock_rdlock + 110
1 XYZ 0x259ac08 CRYPTO_THREAD_read_lock + 10241200
2 XYZ 0x251a184 int_err_get_item + 9714220
3 XYZ 0x2519f0c ERR_lib_error_string + 9713588
4 XYZ 0x2519cd4 ERR_error_string_n + 9713020
5 XYZ 0x260bbfc ossl_strerror + 10704036
6 XYZ 0x260c4e4 ossl_connect_common + 10706316
7 XYZ 0x2610538 Curl_ssl_connect_nonblocking + 10722784
8 XYZ 0x25e2df8 https_connecting + 10536608
9 XYZ 0x25e2d90 Curl_http_connect + 10536504
10 XYZ 0x25f0990 multi_runsingle + 10592824
11 XYZ 0x25f049c curl_multi_perform + 10591556
12 XYZ 0x25d8d28 curl_easy_perform + 10495440

环境信息

  • 操作系统版本:iOS 15
  • Curl版本:7.76.1
  • OpenSSL版本:OpenSSL 1.1.1k 25 Mar 2021

问题场景

多线程中并行发起get/post/multipart等多种类型的网络请求,日常运行正常,但设备进入后台一段时间后就会触发崩溃,崩溃点位于ossl_connect_common函数内。

根因分析
  1. OpenSSL全局错误队列锁状态损坏:崩溃栈顶明确指向pthread_rwlock_rdlock调用失败,对应OpenSSL访问全局错误队列的读锁。iOS进入后台后,系统会暂停非活跃线程的调度,若此时线程持有OpenSSL的全局读写锁,超过后台存活阈值后系统会强制回收线程上下文,导致锁的内部状态被异常篡改,后续其他线程尝试获取读锁时直接触发崩溃。
  2. 依赖版本兼容性缺陷:当前使用的Curl 7.76.1和OpenSSL 1.1.1k存在已知的多线程后台场景兼容性问题:ossl_connect_common函数内获取错误信息时未做线程隔离,多线程并发请求时会同时竞争错误队列的全局锁,后台场景下锁竞争的超时概率大幅提升,最终触发崩溃。
  3. iOS15后台网络限制触发异常回调:iOS15对后台网络请求的限制更严格,后台运行超过30秒的未完成请求会被系统强制中断,中断回调触发时OpenSSL正持有错误队列的读锁,中断上下文异常释放锁后,其他线程访问锁时直接触发非法访问崩溃。
解决方案
  • 优先升级依赖:将Curl升级至7.79.1及以上版本,OpenSSL升级至1.1.1n及以上版本,两个版本均已修复后台场景下的锁状态异常问题,同时修复了ossl_connect_common函数内的错误队列访问竞态问题。
  • 管控后台网络请求:APP触发进入后台回调时,调用curl_multi_pause暂停所有未完成的网络请求,禁止后台发起新的非必要请求,仅允许申请了后台任务权限的请求继续执行,APP回到前台后再恢复所有请求调度。
  • 做线程上下文隔离:每个线程使用独立的Curl easy handle,禁止多线程共享同一个SSL_CTX或者Curl handle,每次请求完成后主动调用ERR_clear_error清空当前线程的OpenSSL错误队列,降低全局锁的竞争概率。
  • 手动补充锁校验:如果暂时无法升级依赖,可自定义OpenSSL的线程锁回调,调用读写锁接口前先校验锁对象的有效性,避免访问已经被系统回收的锁对象。

内容的提问来源于stack exchange,提问作者Saurabh B

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 22:36:02