【问题标题】:C++, Global variables and dynamic shared librariesC++、全局变量和动态共享库
【发布时间】:2014-05-17 09:58:36
【问题描述】:

我知道全局变量很糟糕,但即使是函数的局部静态变量似乎也很糟糕。

我注意到在 linux 上,共享对象(动态库)中的全局变量和静态变量在您第一次使用 dlopen 时会被初始化。但是当你 dlclose,然后再次 dlopen 时,它不会第二次初始化全局变量或静态变量。

我使用 RTLD_NOLOAD 和 dlopen 来测试 dlclose 是否真的删除了库,并且它说它已经删除了,所以这不是引用计数问题。

这与 windows 不同: http://msdn.microsoft.com/en-us/library/988ye33t.aspx 我已经测试过并且确实似乎重新初始化了静态。

这是真的吗,还是我只是在搞砸别的事情?

如果这是真的,这不会使任何类型的静态变量变得危险/无用吗?

【问题讨论】:

  • 来自man 3 dlopenflag RTLD_NODELETE : [...] the library's static variables are not reinitialized if the library is reloaded with dlopen() at a later time. [...]。由于与RTLD_LAZYRTLD_NOW 标志相反,此标志不是强制性的,这是否意味着默认情况下应重新初始化静态变量?
  • 太好了,我不知道有这样的 nix/C++ 函数的手册页。我将看看是否有办法让它像 Windows DLL 一样运行并重新初始化所有内容。但这是否仍然意味着假设有关静态初始化的任何事情都是不好的做法?
  • 我下载了 eglibc 源代码并进入了 dlopen 函数,第二次它确实做了一些不同的事情。但是很难发现选择的位置。该库似乎已成功卸载,因此不应挂在其上。可悲的是 _fini() 在图书馆关闭时似乎无法捕捉。我明天回来再试一次。

标签: c++ linux global-variables shared-libraries


【解决方案1】:

但是当你 dlclose,然后再次 dlopen 时,它不会第二次初始化全局变量或静态变量。

这很可能发生,因为库实际上没有dlclose 上卸载。

来自man dlclose

The function dlclose() decrements the reference count on the dynamic library
handle handle. If the reference count drops to zero and no other loaded
libraries use symbols in it, then the dynamic library is unloaded.

您很可能不满足“没有其他加载的库在其中使用符号”部分。

您可以使用LD_DEBUG=symbols,bindings 运行二进制文件并注意以下消息:

    binding file XXX to libYYY.so: normal symbol `ZZZ'

如果您将libYYY.so 中的任何符号绑定到卸载的文件,则libYYY.so 无法在dlclose 上卸载。

【讨论】:

  • 是的,看起来好像有一个共享符号保持打开状态。这意味着真的,我需要改变我的方法,而不是假设 dlclose 实际上调用了析构函数。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-10
  • 2022-01-02
  • 1970-01-01
  • 2015-03-28
  • 2023-03-20
相关资源
最近更新 更多