CFBundleGetFunctionPointerForName和dlsym为导出的函数返回NULL

时间:2017-09-11 05:18:41

标签: ios frameworks nsbundle dlopen dlsym

我有一个JavaScriptCore框架的分支,我在其中添加了一个我自己的函数,它被导出。框架编译只是找到。在框架上运行nm表明函数(JSContextCreateBacktrace_unsafe)确实已导出:

Leo-Natans-Wix-MPB:JavaScriptCore.framework lnatan$ nm -gU JavaScriptCore.framework/JavaScriptCore | grep JSContextCreateBacktrace
00000000004cb860 T _JSContextCreateBacktrace
00000000004cba10 T _JSContextCreateBacktrace_unsafe

但是,我无法使用CFBundleGetFunctionPointerForNamedlsym获取该功能的指针;两者都返回NULL。首先,我使用dlopen打开我的框架,然后尝试使用CFBundleCreate然后使用CFBundleGetFunctionPointerForName,但这也会返回NULL。

是什么导致这种情况?

更新

有些可疑的事情正在发生。我重命名了一个JSC函数,nm反映了这一点。但是,dlsym仍然能够找到具有原始名称的函数,而不是重命名的函数。

1 个答案:

答案 0 :(得分:2)

很难跟踪它,因为它高度依赖于您的特定环境和环境,但很可能您遇到了这个问题,因为系统映像已经加载并且您没有更改名称框架。

如果查看dyld/dyldAPIS.cpp:1458dlopen的源代码,您会注意到传递给dyld的上下文配置了matchByInstallName = true。然后将此上下文传递给loadloadPhase2执行图像加载所需的各个阶段。有几个阶段值得注意:

    <{3}}中的
  • loadPhase5check提取框架路径的结尾并在搜索路径中搜索

  • dyld/dyld.cpp:2896中的
  • loadPhase5load遍历所有已加载的图像,并确定其中是否有任何匹配的安装名称,如果有,则返回该值而不是加载新的。 / p>

  • {li>

    dyld/dyld:2712中的loadPhase5check如果未被任何先前步骤加载/找到,则最终加载图像。 (值得注意的是JavaScriptCore.framework首先被执行,因为图像加载是一个两遍过程。)

考虑到上述所有情况,我会尝试将您的框架重命名为install_name_tool -id之外的其他内容。根据系统框架和框架的安装名称,我还建议您更改安装名称。 (有很多博客文章和StackOverflow帖子记录了如何使用{{1}}执行此操作。)