- c++11的
的create implement是在thread.cc 中实现的,这意味着创建代码在libstdc++.so 中,创建代码需要使用与平台有关的api - gcc(g++ is a part of gcc)的预期:
- 没有调用的thread的代码,不会产生对pthread的依赖,更重要的,不同配置的gcc的线程模型是不同的,依赖库也不同(即不一定是pthread),如果不去除依赖,这会导致链接的深刻耦合
- 调用了thread的代码,必须要链接到pthread
- gcc 内部,通过弱符号机制来达到这个目的,以foo函数举例:
- 通过一个包装的符号,如gcc_foo, 弱引用到foo
- 声明foo 是一个弱符号,可以在链接时被强符号替代,弱符号默认是未定义的(可能也不是空指针)
- g++的thread.cc 通过gcc_foo 包装后的函数,来创建线程,而不是直接使用平台api
通过弱符号,即便是业务代码没有链接pthread,thread.cc 相关的代码也不会产生链接报错。那么,g++ 又是如何完成2.2. 的呢? 答案是g++ 通过一个无用参数强制产生对pthread 的依赖,这部分实现是在
那么为什么dlopen 又会导致使用了std::thread的库crash呢? 这是因为符号加载顺序的问题,libdl 不是ld,他是glibc的一部分,他通过名字空间等机制支持符号的隔离等。名字空间一般有:local/global 以及其他(可能和加载顺序有关),dlopen 加载一个库时,其查找符号的顺序是:
- LOCAL
- GLOBAl
- 其他
前面说过,因为gcc内部搞了一个弱符号,他是存在应用程序的符号表中的,应用程序的符号表对于dlopen的so而言是全局的。可以明确的是LOCAL肯定没有pthread相关符号,GLOBAL中有gcc定义的弱符号,dl认为找到了,但实际是错误的,从而导致了不能debug的crash
标签:std,gcc,crash,thread,符号,pthread,foo,dlopen From: https://www.cnblogs.com/fyyy94/p/18376351