__dso_handle 定义在哪里?

28

在编译我的程序时,出现了未解决符号错误,指控无法找到__dso_handle。通常这个函数在哪个库中定义?

nm on libstdc++.so.6的以下结果是否意味着它包含该函数?

我尝试链接它,但错误仍然发生。

nm libstdc++.so.6 | grep dso
00000000002fc480 d __dso_handle
3个回答

25

__dso_handle是一个“保护程序”,用于在全局销毁期间标识动态共享对象

实际上,你应该停止阅读。如果你试图通过操纵 __dso_handle 来破坏对象识别,那么很可能出现问题。

然而,既然你问它的定义在哪里:答案比较复杂。想要查看其定义位置(对于GCC),在C++文件中使用,并在此之后执行extern int __dso_handle;。由于类型冲突,这应该会显示声明的位置(有关来源,请参见此论坛帖子)。

有时,它可以 手动定义

有时候,它由编译器安装的“运行时”定义/提供(实际上,CRT通常只是一堆二进制头文件/入口点管理代码和一些退出保护/处理程序)。在GCC中(不确定其他编译器是否支持此功能;如果支持,则会在它们的源代码中): 通常,它在stdlib中定义:

更多阅读:


18

我遇到了这个问题。以下是似乎会可靠地生成问题的条件:

  1. -nostdlib 连接 g++ 时没有使用 C/C++ 标准库(典型的小型嵌入式场景)。
  2. 定义一个静态分配的标准库对象;特定于我的情况是静态分配的 std::vector。以前,静态分配的 std::array 没有任何问题。显然,并非所有的 std:: 静态分配对象都会引起这个问题。
  3. 请注意,我没有使用任何类型的共享库。
  4. 正在使用GCC/ARM 交叉编译器

如果您的情况是这样,那么只需在您的编译/链接命令行中添加命令行选项:-fno-use-cxa-atexit

这里有一个非常好的链接 __dso_handle 的使用作为“动态共享对象句柄”

该页面中似乎存在一个拼写错误,但我不知道应该联系谁来确认:

在调用对象的构造函数析构函数之后,GCC 自动调用该函数……

我认为这应该是“一旦所有析构函数都被调用后,GCC 调用该函数”……

确认的一种方法是按照提到的实现 __cxa_atexit 函数,然后单步运行程序并查看它在哪里被调用。我以后会试试,但现在不行。


考虑到其他答案,这会导致内存泄漏吗? - vesperto
1
在我的情况下,添加-fno-use-cxa-atexit没有改变错误输出。我的错误是:undefined reference to `__dso_handle' 我在g++调用中使用了-nostdlib。 - skittlebiz

2

在@natersoz的回答基础上-

对我来说,使用-Wabi-tag -D_GLIBCXX_USE_CXX11_ABI=0-fno-use-cxa-atexit一起编译一个旧的库有所帮助。如果错误消息中的C++函数包含std::__cxx11,则说明由于ABI更改而发生了变化。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接