2017-08-01 57 views
7

在macOS 10.12.6上,我有一个共享库和一个可执行文件(都是自己构建的,SIP不应该申请AFAIK),我想预加载可执行文件库。它失败,为1的返回码,默默否则:DYLD_FORCE_FLAT_NAMESPACE = 1 DYLD_INSERT_LIBRARIES =。/ foo/my.dylib ./bar/exec返回1不运行我的可执行文件

$ ./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 

如果我添加任何DYLD_PRINT_LIBRARIESDYLD_PRINT_LIBRARIES_POST_LAUNCH选项中man dyld记录,他们都表明,无论是库和可执行文件已经成功加载:

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

如果我尝试运行在任何dtruss或LLDB预载可执行文件,它运行,而无需预装库。这可能是有道理的,因为这些工具是SIP保护的。

我该如何去调试呢?

UPDATE

感谢@macmoonshine,我能够从自身LLDB设置预载的环境,而不是用于LLDB重现下LLDB返回码1退出:

(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 

这是开始调试。

+0

您是否试过在'lldb'中运行它以获取堆栈跟踪? – clemens

+0

我有,正如我在问题中所写的那样 - 图书馆默默无法预装,因此我不确定在lldb中我应该寻找什么堆栈跟踪? –

+0

如果你在'lldb'中运行可执行文件,它也会崩溃。 'lldb''会告诉你碰撞位置,如果在碰撞后输入'bt'。 – clemens

回答

4

您可以在lldb,在那里你可以用env命令设置的环境中运行代码:

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

随着lldb,直到它崩溃,你可以运行程序。如果它与exit()(或_exit())存在异常,则应使用b exitb _exit来设置符号断点。所以你有机会在失败的地方进行回溯。