我有一个在 iOS 应用程序中使用的 C 库。该库使用 dlopen()
访问扩展功能。该代码在 iOS 模拟器上运行良好(在 32 位和 64 位模式下);然而,当我在实际的 iPhone5s (ARM64) 上运行相同的代码时,出现以下错误:
dlopen(/private/var/mobile/Containers/Bundle/Application/EDEAE282-AE96-45CA-9A4F-D70EE532FB93/foobar.app/lib/time.so, 2): no suitable image found. Did find:
/private/var/mobile/Containers/Bundle/Application/EDEAE282-AE96-45CA-9A4F-D70EE532FB93/foobar.app/lib/time.so: mmap() error 1 at address=0x101CE4000, size=0x00004000 segment=__TEXT in Segment::map() mapping /private/var/mobile/Containers/Bundle/Application/EDEAE282-AE96-45CA-9A4F-D70EE532FB93/foobar.app/lib/time.so
据我所知,该文件存在并且正在成功找到。这也不仅仅是为错误的体系结构编译的问题; lipo -info
报告 time.so
是:
Non-fat file: time.so is architecture: arm64
和 file
将 time.so
报告为 Mach-O 64 位包
。
我的两个问题:
“找不到合适的图像”和“mmap() 错误 1”错误消息是什么意思?
如何更正(甚至诊断)这里发生的事情?我单步执行了 C 代码,
dlopen()
调用失败,返回值为NULL
,并设置了错误消息,因此单步执行代码是会给我更多的信息。
(作为背景,- 我正在尝试将 Python 移植到 iOS;对 dlopen()
的调用用于加载 native 代码模块。time.so
是这些模块之一)。
最佳答案
问题一:“找不到合适的图片”是什么意思
[回答] 您是否尝试设置 export LD_LIBRARY_PATH 或 set -rpath 而不是
问题2:“mmap() error 1”错误信息是什么意思。
[回答]
一种可能性: 基本上,dlopen 所做的关键点是在磁盘文件中的库与系统 RAM 之间建立内存映射。
" mmap() error 1 at address=0x101CE4000, size=0x00004000 "
意味着操作系统会将文件映射到虚拟内存地址 0x101CE4000(页面对齐),大小为 4 页大小(16384 字节)。
由于这样的尝试失败了,我怀疑你系统内存中的空闲内存是否足以承载映射。
另一种可能性:
dlopen 中使用的 mmap 可能使用 MAP_FIXED 标志进行映射,因此它可能以内核选择要映射的虚拟地址但其属性不可执行的条件结束。
来自 mmap 的手册页:
“prot 参数要求 PROT_EXEC,但映射区域属于文件系统上的一个文件,该文件已挂载为 no-exec。”
如果您可以更改 dlopen() 文件,只需删除 MAP_FIXED 标志(如果有的话)。
总而言之,了解通过 mmap() 设置的错误值(不是返回值)是什么很有趣。您可以使用“strace”来做到这一点,它会显示系统调用失败的原因。
关于ios - 如何在 iOS 设备上诊断 dlopen() 中的故障,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28769040/