尝试编译我的程序时出现未解决的符号错误,抱怨找不到
__dso_handle
。这个函数通常定义在哪个库中?
nm on libstdc++.so.6
的以下结果是否意味着它包含该内容?
我尝试链接它,但错误仍然发生。
nm libstdc++.so.6 | grep dso
00000000002fc480 d __dso_handle
__dso_handle
是一个“守卫”,用于在全局销毁期间识别动态共享对象。
Thom Chiovoloni 写了
__dso_handle
在调试与之相关的问题时的简明描述:
是一个魔法符号,每个__dso_handle
都有不同的值(它是加载程序提供的隐藏符号)。它用于...让运行时(“运行时”= libc + loader + ...)知道线程本地 dtor 适用于哪个共享库,这允许运行时避免某些情况下调用函数指针的情况来自卸载的模块。.so
实际上,你应该停止阅读这里。如果您试图通过弄乱
__dso_handle
来击败对象识别,那么很可能出了大问题。
但是,既然你问它是在哪里定义的:答案很复杂。要显示其定义的位置(对于 GCC),请在 C++ 文件中使用
iostream
,然后执行 extern int __dso_handle;
。由于类型冲突,这应该会显示声明的位置(有关来源,请参阅此论坛主题)。
有时,它是手动定义的。
有时,它是由编译器安装的“运行时”定义/提供的(实际上,CRT通常只是一堆二进制标头/入口点管理代码,以及一些退出防护/处理程序)。在 GCC 中(不确定其他编译器是否支持此功能;如果支持,它将在其源代码中):
通常,它是在 stdlib 中定义的:
进一步阅读:
我遇到了这个问题。以下是似乎可靠地产生故障的条件:
-nostdlib
(典型的小型嵌入式场景)。std::vector
。以前这是 std::array
静态分配的,没有任何问题。显然并非所有std::
静态分配的对象都会导致问题。如果这是您的用例,则只需将命令行选项添加到您的编译/链接命令行中:
-fno-use-cxa-atexit
这是一个非常好的链接,指向 __dso_handle 用法作为“动态共享对象的句柄”。
页面似乎有拼写错误,但我不知道该联系谁来确认:
调用对象的构造函数和析构函数后,GCC 会自动调用该函数...
我认为这应该是“一旦调用了所有析构函数,GCC 就会调用该函数”...
确认这一点的一种方法是实现如上所述的
__cxa_atexit
函数,然后单步执行程序并查看它在哪里被调用。有一天我会尝试一下,但不是现在。
添加到@natersoz的答案-
对我来说,使用
-Wabi-tag -D_GLIBCXX_USE_CXX11_ABI=0
和 -fno-use-cxa-atexit
有助于编译旧的库。一个明显的迹象是,由于 ABI 更改,错误消息中的 C++ 函数是否包含
std::__cxx11
。