如何允许和正确加载.so文件的修改?

时间:2012-08-07 15:41:18

标签: c++ linux shared-libraries ld

我使用.so作为我的程序的一种插件,允许应用用户定义的逻辑。程序的Muliuple实例将运行,每个实例都有自己的特定.so,它定义了该程序实例的用户特定逻辑。该程序理想情况下将无限运行,但有时需要更改某些逻辑,因此我有一个明智的想法,即检测.so是否被修改并上传新的.so。这样就可以在不杀死/重启程序的情况下更改特定的实现逻辑(这可能会导致数据丢失)。

我有loadPlugin函数正常工作,我正在使用inotify来检测.so何时被更改并再次加载它。这没有按计划运作。我假设所有.so都被加载到内存中,从那时起完全独立于物理文件,但显然不是这样。如果我在没有警告的情况下更改.so文件,我的程序会因为段错而崩溃。如果我是.so然后复制一个新版本,程序不会崩溃 - 我告诉它知道在删除时将插件的版本保留在内存中。但是,当我的loadPlugin方法开始尝试加载新修改的.so时,它只返回对 .so方法的引用,而不是新方法。我假设它默认使用已经加载到内存中的版本,因为它假设它们是相同的,但我特别希望它加载新版本!因为只有一个应用程序会使用那个.so,并且当我在新的.so中加载时,我不会调用.so的方法。可以安全地覆盖.so的定义如果我知道如何实现这一目标。

我想知道解决这些问题的最佳方法是什么?我的第一个想法是在加载之前将.so文件的一个版本复制到另一个位置,这样即使原始文件被修改,我的程序也不会崩溃,但这并不能解决主要问题。如何告诉inotify忽略它在内存中的.so文件的缓存版本并加载新版本的插件?我是否需要在两个单独的文件(plugin1.so,plugin2.so)之间交替,以便在运行plugin1.so时我可以修改plugin2.so并加载它,释放plugin1.so进行更改?这会不会起作用,或者在我读完它们之后最终会将这两个版本“缓存”并且第三次更改时无法加载插件?

PS。我敢肯定你猜对了,但我在Linux上使用C ++(特别是redhat或centos)。我可以在最终的运行时环境中定义我的操作系统,所以虽然可移植性总是很好,但如果唯一的方法不可移植,我就不需要它。

2 个答案:

答案 0 :(得分:1)

您是否尝试在更新时为插件设置不同的SONAME? SONAME可以区分同一个库的不同版本,这几乎就是您所要求的。

如果你在你的机器上查看/ usr / lib或/ lib,并想知道谁在那里定义了哪些符号链接,那么它就是各个库的SONAMES; - )

man ldman gcc应告诉您如何在链接时指定SONAME。

答案 1 :(得分:1)

Dani指出问题出在我的dlclose电话中。我正在传递错误的标题而没有正确关闭DL。不久我修复了我可以正确加载更新的方法。仍然有一个问题,文件的更改导致程序被杀,但我知道如果需要,我可以解决这个问题。