Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to diagnose failures in dlopen() on iOS devices

Tags:

c

ios

dlopen

I've got a C library that is being used in an iOS app. This library uses dlopen() to access extension functionality. The code works fine on the iOS simulator (in both 32 bit and 64 bit modes); however, when I run the same code on an actual iPhone5s (ARM64), I get the following error:

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

As far as I can make out, the file exists and is being found successfully. It's also not just a problem of being compiled for the wrong architecture; lipo -info reports that time.so is:

Non-fat file: time.so is architecture: arm64

and file reports time.so as a Mach-O 64-bit bundle.

The two questions I have:

  1. What does the "no suitable image found" and "mmap() error 1" error messages mean?

  2. How do I correct (or even diagnose) what is going on here? I've stepped through the C code, and the dlopen() call is failing with a return value of NULL, and setting the error message, so stepping through the code isn't going to give me any more information.

(As background, - I'm trying to port Python to iOS; the call to dlopen() is used to load native code modules. time.so is one of those modules).

like image 437
freakboy3742 Avatar asked Feb 27 '15 15:02

freakboy3742


2 Answers

Question 1: What does the "no suitable image found

[Answer] Have you tried to set export LD_LIBRARY_PATH or set -rpath instead

Question 2: What does the "mmap() error 1" error messages mean.

[Answer]

One possibility: Basically,the key point dlopen does is to establish the memory mapping between your library in disk file to the system RAM.

" mmap() error 1 at address=0x101CE4000, size=0x00004000 "

means that OS will map the file into a virtual memory address 0x101CE4000(which is page aligned) and size is 4 pages size(16384 byte).

since such attempt is failed,I suspect whether your free memory in your system ram is enough to carry the mapping.

Another possibility:

the mmap used in dlopen might use MAP_FIXED flag to do the mapping so it is possible it ends up with a condition that a kernel choose a virtual address to be mmaped but its property is not executable.

From the man page in mmap:

"The prot argument asks for PROT_EXEC but the mapped area belongs to a file on a file system that was mounted no-exec."

If you can change the dlopen() file, just remove MAP_FIXED flag if any.

In sum, it is interesting to understand what is the error value(not return value) set via mmap(). You can do that by using "strace" which would show why system call is failed.

like image 114
kikigood Avatar answered Oct 02 '22 12:10

kikigood


I'v encountered the same problem. When I dlopen a framework, Xcode says dlopen mmap() error 1.

Make sure you'v singed the framework and host app with the same identity.

like image 28
Nix Wang Avatar answered Oct 02 '22 11:10

Nix Wang