问题标签 [gold-linker]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - c++17,lto,-static-libstdc++ 问题:警告:重定位指的是带有 ld.gold 的废弃部分,然后是 __run_exit_handlers 中的段错误
我正在就如何调试一个我无法简化为最小示例的重大问题提出一些建议。
问题:我编译了链接到许多不同库的应用程序。标志包括:
-static-libstdc++ -static-libgcc -pipe -std=c++1z -fno-PIC -flto=10 -m64 -O3 -flto=10 -fuse-linker-plugin -fuse-ld=gold -UNDEBUG -lrt -ldl
编译器是 gcc-7.3.0,针对 binutils-2.30 编译。Boost 使用与程序其余部分相同的标志进行编译,并静态链接。
当程序被链接时,我在我自己的代码和 boost 中都收到关于重定位引用丢弃部分的各种警告。例如:
然后当我运行程序时,它会在销毁时出现段错误,并带有回溯:
试图调用的函数指针是 0x0。
如果我使用 static-libstdc++ 删除,链接器警告和运行时段错误就会消失。
如果我从 c++1z 更改为 c++14,链接器警告和运行时段错误就会消失。
如果我删除 -flto,链接器警告和运行时段错误就会消失。
如果我在编译标志中添加“-g”,链接器警告和运行时段错误就会消失。
我曾尝试通过指定 -Wl,--debug=all 来要求黄金进行额外的调试,但它似乎告诉我没有任何相关性。
如果我尝试使用一小部分看起来相关的代码,单独编译并将其链接到相同的 boost 库(即尝试生成最小示例),则没有链接器警告,并且程序运行完成没有问题.
帮助!我能做些什么来缩小问题的范围?
maps - 如果使用链接 -static-libstdc++ 创建一个空的 dso,则 Dlclose 无法工作
我想将整个 stdlibc+ 编译/链接成一个独立的 C++ 支持。所以我做了一个空的so文件,只包含声明extern "C" void * __dso_handle = 0
和导出所有符号链接它
并设置链接标志-nostdlib
一切都按预期工作,除了我无法通过调用从内存中取消映射它,dlclose()
即使我立即调用dlclose()
after dlopen()
。当我使用 command 时它仍然存在cat /proc/pid/maps
。
然后我LD_DEBUG=binding
用来加载dso文件。我发现它有很多绑定到libc.so.6
,的符号libstdc++.so.6
。我猜当系统将 dso 文件加载到内存中时,它会将默认函数指针指向静态链接 stdc+ 到 dso 文件中的 dso 函数。
我的问题是:是否可以从内存中取消映射 dso 文件dlclose()
?也许系统不支持将函数指针重新绑定到默认地址,因此它不支持从内存中卸载库dlclose()
。我对吗?或者我有什么办法吗?
我也尝试不使用-nostdlib
并删除代码extern "C" void * __dso_handle = 0
,因此 so 完全是空的,但仍然无法通过 use 将其从内存中卸载dlclose
。我现在不知道。
2018 年 4 月 25 日更新
现在使用gold和-Wl,-no-GNU-unique可以成功从内存中卸载库,但是调用dlclose后退出时会导致应用程序崩溃。堆栈如下:
不知道为什么。我将使用 --disable-GNU-unique-object 重新构建 GCC 以重试。我做了一个示例 repo 在这里重现这个问题。
使用-disable-GNU-unique-object,甚至不使用gold 和-Wl,-no-GNU-unique 来编译和链接重建的GCC 也存在崩溃。
在此处更新 2018 年 4 月 26 日。如果您有兴趣,请在此处查看我的存储库,其中包含崩溃和修复的 dso 项目的源代码,您可以复制和比较有关编译器和使用的链接器选项的更改和固定细节。如果发生任何新问题,将保持更新。最后非常感谢@yugr :)。
从 Chrome 添加一个新的工具提取似乎是线程安全的,把它放在这里作为备份解决方案。不确定哪一个是最好的。
使用黄金链接的所以不能将任何 C++ 函数包装memcpy
到其中,如下所示并链接--wrap=memcpy
这适用于ld-bfd
,但不适用于gold
。原因是黄金包装了所有版本的符号,所以调用memcpy
变成了__wrap_memcpy
导致无限递归的调用。欲了解更多详情,请参阅此处。但是在我这边,即使我使用它也不起作用__wrap_memcpy
,__real_memcpy
它仍然会导致无限的安全。最后通过 memmove 实现 __wrap_memcpy 修复它。
所以它包含包装memcpy
和独立于 stdc+ 库。
静态链接 stdc+ 库中的内存泄漏问题更多细节在这里。
build - 在哪里可以找到所有 ldflags 快捷方式或其文档?
当构建系统告诉我它找到了对某些东西的未定义引用时,我总是感到困惑。很明显,未定义的引用错误与最终链接有关,因此它LDFLAGS
与构建系统中的变量有关。但是如何找到 package 到底想要什么?例如,如果包链接-lm
它意味着它想要libm
,但我遇到了更多这些标志,有时即使在查看构建系统之后我也不知道它们来自哪里。有没有一种通用的方法来解决这个问题,或者一些提示?
unix - Gold 无法从静态库中创建可重定位目标文件
让我先说我是与链接器相关的事情的菜鸟。如果我说的话似乎没有意义,它可能没有 - 请打电话给我。
我有以下文件:
/li>bar.rs
/li>foo.c
我可以将它们链接到一个可重定位的目标文件中:
我不确定幕后发生了什么,但我确实得到了我想要的输出:bar
并且foo
定义了,而baz
没有定义。
如果我替换ld
为ld.bfd
. 然而,事情分崩离析ld.gold
。
这ld.gold
与 binutils 2.24 和 2.26 一起打包。
binutils 2.30 的问题仍然存在,尽管我得到的行号不同:
--emit=obj
此外,即使使用而不是,错误仍然存在--crate-type=staticlib
所以:
- 错误是什么意思?
- 如何使用
ld.gold
asld
和实现相同的可重定位对象输出ld.bfd
?
dynamic - 没有 STB_GNU_UNIQUE 的静态链接 stdc++ 在 dlclose 时导致内存泄漏
我必须制作一个静态链接stdc++的dso,并且需要可以从内存中动态卸载。所以我尝试编译 gcc并使用带有选项的--disable-gnu-unique-object
黄金链接。-Wl,--no-gnu-unique
但是两者都包含内存泄漏问题,即使我除了调用dlopen() dlclose()
main 什么都不做。测试代码如:
比我检查之前和之后的内存cat /proc/pid/maps
,我发现每次只有堆变化越来越大。在 1000 次调用 dlopen & dlclose 后大约 90M 对我来说 90M 仍然太大。
在谷歌上搜索了大约 2 周后,但对这个问题没有任何帮助。只在此处找到如下所述的文件。
-fno-gnu-unique 在具有最新 GNU 汇编器和 C 库的系统上,C++ 编译器使用“STB_GNU_UNIQUE”绑定来确保内联函数中模板静态数据成员和静态局部变量的定义是唯一的,即使存在“ RTLD_LOCAL"; 这是必要的,以避免两个不同的“RTLD_LOCAL”插件使用的库出现问题,这取决于其中一个插件的定义,因此在符号绑定方面不同意另一个。但这会导致受影响的 DSO 忽略“dlclose”;如果您的程序依赖于通过“dlclose”和“dlopen”重新初始化 DSO,则可以使用 -fno-gnu-unique。
这是一个Linux错误吗?有没有人可以帮助我解决这个问题?谢谢。环境是 gcc 5.3.1。我与定义 _GLIBCXX_USE_CXX11_ABI 相关联。
c++ - 使用 libpthread 在共享库中未定义的行为,但在 ELF 中没有作为依赖项
当“正确”链接(进一步解释)时,下面的两个函数调用都会在 pthread 调用实现时无限期阻塞,cv.notify_one
并且cv.wait_for
:
当上述共享库用于以下应用程序时:
问题仅在链接时重现libodr.so
:
- 与 g++
- 带黄金链接器
-lpthread
作为依赖提供
使用以下版本的相关工具:
Linux Mint 18.3 Sylvia
binutils 2.26.1-1ubuntu1~16.04.6
g++ 4:5.3.1-1ubuntu1
libc6:amd64 2.23-0ubuntu10
所以我们最终得到:
__pthread_key_create
在 PLT 中定义为 WEAK 符号- 没有
libpthread.so
作为 ELF 中的依赖项
如此处所示:
另一方面,对于以下任何一种情况,我们都不会遇到错误:
- 铿锵++
- bfd 链接器
- 没有明确的
-lpthread
-lpthread
但与-Wl,--no-as-needed
注意:这次我们有:
NOTYPE
并且没有libpthread.so
依赖WEAK
和libpthread.so
依赖
如此处所示:
可以在这里找到编译/运行的完整示例:https ://github.com/aurzenligl/study/tree/master/cpp-pthread
什么时候使用 pthread 破坏 shlib并且在 ELF 中找不到依赖项__pthread_key_create
?动态链接器是否从(stubs) 获取 pthread 符号而不是?WEAK
libpthread.so
libc.so
libpthread.so
linker - gold 和标准 (bfd) 链接器之间的库选择规则有何不同?
我知道标准 ld.bfd 以指定的顺序处理静态库,从每个库中提取满足未满足(在那个时间点)依赖的任何对象。黄金是否遵循相同的过程,这是否记录在任何地方?
我看到一个案例,其中黄金比 ld.bfd 多引入一个 *.so 文件(我正在使用 --as-needed 选项),并试图找出原因以及一般情况下还有哪些其他差异我应该留意一下。
linker - 使用 ld.gold 将静态库直接链接到可执行文件
我有一个libfoo.a
包含_start
可执行文件的所有必需符号。ld.bfd -o foo libfoo.a
在我的情况下工作顺利。但是,ld.gold -o foo libfoo.a
无法以静默方式生成没有来自libfoo.a
. 创建一个空a.o
并将其与ld.gold -o foo a.o libfoo.a
作品链接。
我想知道有什么方法可以直接将静态库链接到可执行文件中,ld.gold
而无需创建冗余的空目标文件?
llvm - Clang 构建速度极慢,中间挂了
我开始编写自己的 clang 工具。这些是我到目前为止所遵循的步骤:
- 签出 llvm 7.0 发行版
- 签出 clang 7.0 发布版本
使用带有以下标志的 ninja 构建了 clang 和 llvm(没有这些,它一直挂在我身上)
-DLLVM_USE_LINKER=gold -DLLVM_PARALLEL_LINK_JOBS=1 -DLLVM_LINK_LLVM_DYLIB=true -DLLVM_USE_SPLIT_DWARF=ON -DBUILD_SHARED_LIBS=ON
安装铿锵
现在我想将 clang 设置为它自己的编译器。所以我使用'ccmake ../llvm'在配置文件中设置了这些标志。我不确定这是否是正确的做法?现在我尝试构建clang,它说检测到的链接器是GNU ld。如何重置我的配置文件并实际更改链接器以使其更快?我有 8GB 内存。
其次,每次编写工具时,我是否必须一次又一次地构建 clang?每次需要3-4个小时吗?
更新
正如 sandthorn 在评论中所建议的那样,我通过使用将并行作业限制为 1 ninja -j 1
。但是,构建再次失败并出现以下错误:
在此之后,还有大约 100 个其他未定义的参考错误。
gcc - 如果编译器搜索路径中存在 real-ld 可执行文件,如何强制 GCC 使用 ld.gold?
我发现当 GCC(在 GCC 4.8 和 GCC 6.4 上尝试过)real-ld
在其搜索路径中找到可执行文件时,它会默默地忽略-fuse-ld=...
选项,并使用real-ld
而不是适当的链接器。
通常,没有real-ld
它会按预期工作:
GCC 的文档表明gold
将使用链接器。
collect2 的文档没有说明任何关于-fuse-ld
功能的内容......