DYLD_FORCE_FLAT_NAMESPACE = 1 DYLD_INSERT_LIBRARIES =. / Foo / my.dylib. / Bar / exec returns 1 without starting my executable

On macOS 10.12.6, I have a shared library and an executable (both are created by themselves, SIP should not be used by AFAIK), and I would like to preload the library for the executable. It does not work with return code 1 and silently otherwise:

$ ./bar/exec <does stuff> $ DYLD_FORCE_FLAT_NAMESPACE=1 DYLD_INSERT_LIBRARIES=./foo/my.dylib ./bar/exec <returns immediately> $ echo $? 1 # 1 is not an explicitly returned value from ./bar/exec 

If I add the options DYLD_PRINT_LIBRARIES or DYLD_PRINT_LIBRARIES_POST_LAUNCH as described in man dyld , they both show that both the library and the executable were loaded successfully:

 ... dyld: loaded: /full/path/to/exec dyld: loaded: ./foo/my.dylib ... 

If I try to run the executable file with preload in dtruss or lldb, it starts without preloading the library. This may make sense as these tools are protected by SIP.

How can I debug this?

UPDATE

Thanks to @macmoonshine, I can reproduce the output of return code 1 under lldb by setting the preboot environment from LLDB itself, not LLDB:

 (lldb) env DYLD_FORCE_FLAT_NAMESPACE=1 DYLD_INSERT_LIBRARIES=./foo/my.dylib (lldb) run ... Process 24130 stopped * thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1 frame #0: 0x00007fffc8aac310 libsystem_kernel.dylib`__exit ... (lldb) bt * thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1 * frame #0: 0x00007fffc8aac310 libsystem_kernel.dylib`__exit frame #1: 0x000000010008ebac my.dylib`my_init at my.c:86 [opt] frame #2: 0x0000000100018a1b dyld`ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) + 385 frame #3: 0x0000000100018c1e dyld`ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) + 40 frame #4: 0x00000001000144aa dyld`ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) + 338 frame #5: 0x0000000100013524 dyld`ImageLoader::processInitializers(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) + 138 frame #6: 0x00000001000135b9 dyld`ImageLoader::runInitializers(ImageLoader::LinkContext const&, ImageLoader::InitializerTimingList&) + 75 frame #7: 0x0000000100005434 dyld`dyld::initializeMainExecutable() + 125 frame #8: 0x00000001000098c6 dyld`dyld::_main(macho_header const*, unsigned long, int, char const**, char const**, char const**, unsigned long*) + 3966 frame #9: 0x0000000100004249 dyld`dyldbootstrap::start(macho_header const*, int, char const**, long, macho_header const*, unsigned long*) + 470 frame #10: 0x0000000100004036 dyld`_dyld_start + 54 

This is the beginning for debugging.

+6
dyld macos
source share
1 answer

You can run your code in lldb , where you can install the environment using the env command:

 env DYLD_FORCE_FLAT_NAMESPACE=1 env DYLD_INSERT_LIBRARIES=./foo/my.dylib run 

With lldb you can run your program until it crashes. If it exists abnormally with exit() (or _exit() ), you should set symbolic breakpoints with b exit and b _exit . Thus, you have a chance to get a return track where it does not work.

+3
source share

All Articles