__dso_handle 定义在哪里?

问题描述 投票:0回答:3

尝试编译我的程序时出现未解决的符号错误,抱怨找不到

__dso_handle
。这个函数通常定义在哪个库中?

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

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

nm libstdc++.so.6 | grep dso
00000000002fc480 d __dso_handle
linker llvm libstdc++
3个回答
25
投票

__dso_handle
是一个“守卫”,用于在全局销毁期间识别动态共享对象

Thom Chiovoloni 写了

__dso_handle
在调试与之相关的问题时的简明描述:

__dso_handle
是一个魔法符号,每个
.so
都有不同的值(它是加载程序提供的隐藏符号)。它用于...让运行时(“运行时”= libc + loader + ...)知道线程本地 dtor 适用于哪个共享库,这允许运行时避免某些情况下调用函数指针的情况来自卸载的模块。

实际上,你应该停止阅读这里。如果您试图通过弄乱

__dso_handle
来击败对象识别,那么很可能出了大问题。

但是,既然你问它是在哪里定义的:答案很复杂。要显示其定义的位置(对于 GCC),请在 C++ 文件中使用

iostream
,然后执行
extern int __dso_handle;
。由于类型冲突,这应该会显示声明的位置(有关来源,请参阅此论坛主题)。

有时,它是手动定义的

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

通常,它是在 stdlib 中定义的:

进一步阅读:


18
投票

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

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

如果这是您的用例,则只需将命令行选项添加到您的编译/链接命令行中:

-fno-use-cxa-atexit

这是一个非常好的链接,指向 __dso_handle 用法作为“动态共享对象的句柄”

页面似乎有拼写错误,但我不知道该联系谁来确认:

调用对象的构造函数和析构函数后,GCC 会自动调用该函数...

我认为这应该是“一旦调用了所有析构函数,GCC 就会调用该函数”...

确认这一点的一种方法是实现如上所述的

__cxa_atexit
函数,然后单步执行程序并查看它在哪里被调用。有一天我会尝试一下,但不是现在。


2
投票

添加到@natersoz的答案-

对我来说,使用

-Wabi-tag -D_GLIBCXX_USE_CXX11_ABI=0
-fno-use-cxa-atexit
有助于编译旧的库。一个明显的迹象是,由于
ABI 更改
,错误消息中的 C++ 函数是否包含 std::__cxx11

© www.soinside.com 2019 - 2024. All rights reserved.