« MonkeyBread Software … | Home | Heatmaps with the Mon… »

Common problems loading a dynamic library on macOS

From time to time we get bug reports about some variation of library not loading. There are various reasons and I collected a few problems loading MySQL (or MariaDB) client libraries here.

First the error when no library is set:

libmysqlclient.dylib.21: dlopen(libmysqlclient.dylib.21, 1): image not found
	 libmysqlclient_r.dylib: dlopen(libmysqlclient_r.dylib, 1): image not found
	 libmysqlclient_r.15.dylib: dlopen(libmysqlclient_r.15.dylib, 1): image not found
	 libmysqlclient_r.16.dylib: dlopen(libmysqlclient_r.16.dylib, 1): image not found
	 libmysqlclient_r.18.dylib: dlopen(libmysqlclient_r.18.dylib, 1): image not found
	 libmysqlclient.dylib: dlopen(libmysqlclient.dylib, 1): image not found
	 libmariadb.dylib.3: dlopen(libmariadb.dylib.3, 1): image not found
	 libmariadb.dylib.2: dlopen(libmariadb.dylib.2, 1): image not found
	 libmariadb.dylib: dlopen(libmariadb.dylib, 1): image not found

You didn't specify where the library is, so SQLAPI tried to load various variations of library names in case those got installed. Now let's say you pass a file path:

dlopen(Applications/FileMaker Pro 18 Advanced/FileMaker Pro 18 Advanced.app/Contents/Frameworks/libmysqlclient.21.dylib, 1): 
	 no suitable image found.  Did find:
	 file system relative paths not allowed in hardened programs

The file path misses the / on the front and thus is a relative path. But that is forbidden for library loading for applications using hardened runtime, which is more strict for improved security.

dlopen(/Users/test/Desktop/libmysqlclient.18.dylib, 1): image not found

And now the file path is simply wrong, so no image found. The file simply doesn't exist and you check the file path.

dlopen(/Users/test/Desktop/libmysqlclient.18.dylib, 1): no suitable image found.  Did find:
	/Users/test/Desktop/libmysqlclient.18.dylib: stat() failed with errno=13

Here again an error with missing image, but now with error 13. This is a permission error as there is a folder named test, but you are not allowed to look inside. The last two errors happen usually when you use the local path for your development machine on the server in production.

dlopen(/Users/cs/Desktop/libmysqlclient.16.dylib, 1): no suitable image found.  Did find:
	/Users/cs/Desktop/libmysqlclient.16.dylib: mach-o, but wrong architecture
	/Users/cs/Desktop/libmysqlclient.16.dylib: stat() failed with errno=22

Now you got a dylib file, but it is of the wrong architecture. This may be having 32-bit library, but 64-bit application.

dlopen(/usr/local/mysql/lib/libmysqlclient.dylib, 1): no suitable image found.  Did find:
	/usr/local/mysql/lib/libmysqlclient.dylib: mach-o, but wrong architecture

The same problem, but now it tried to load the library of local mysql installed on the computer. This error usually results of a 64-bit mySQL and a 32-bit application. But can also now happen with a mysql server for Intel, but a native Apple M1 optimized application on a recent Mac with M1 CPU.

dlopen(/Users/cs/Downloads/libmariadb.3.dylib, 1): no suitable image found.  Did find:
	/Users/cs/Downloads/libmariadb.3.dylib: code signature in (/Users/cs/Downloads/libmariadb.3.dylib) 
	 not valid for use in process using Library Validation: library load disallowed by system policy
	/Users/cs/Downloads/libmariadb.3.dylib: stat() failed with errno=22

Now you got a library, but you are not allowed to just run a library loaded from the website. A good thing to protect novice users. Your users should always get it as part of a notarized download. You as developer may just build a library yourself from source code or get it from a trusted source. Still you may just remove the quarantine of the library by importing it into a container field and exporting it again.

Another variation with error 34:

dlopen(/Users/cs/Desktop/libmysqlclient.21.dylib, 1): no suitable image found.  Did find:
	/Users/cs/Desktop/libmysqlclient.21.dylib: code signature in (/Users/cs/Desktop/libmysqlclient.21.dylib) 
	 not valid for use in process using Library Validation: library load disallowed by system policy
	/Users/cs/Desktop/libmysqlclient.21.dylib: stat() failed with errno=34

Error 34 indicates that it misses a related library. If that one is there, you get error 22 like above.

If the code signature is broken, e.g. a byte is modified in the dylib after code signing, you get a crash report with this:

	Exception Type:        EXC_BAD_ACCESS (Code Signature Invalid)
	Exception Codes:       0x0000000000000032, 0x000000012aadd550
	Exception Note:        EXC_CORPSE_NOTIFY

	Termination Reason:    Namespace CODESIGNING, Code 0x2

The whole application is terminated for the invalid code signature.

Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:       KERN_INVALID_ADDRESS at 0x0000000000000000
Exception Note:        EXC_CORPSE_NOTIFY

Termination Signal:    Segmentation fault: 11
Termination Reason:    Namespace SIGNAL, Code 0xb
Terminating Process:   exc handler [3816]

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   ???                           	000000000000000000 0 + 0
1   de.monkeybreadsoftware.fmplugin.MBS	0x000000011434045d myAPI::LoadAPI() + 573

This is a variation where you passed a valid library with code signature, but the wrong one. A function is loaded, but that failed.

You have a question or found another issue? Please let us know.

13 07 21 - 14:58