C++ 如何知道进程是否真正使用dlclose()ed库完成了?
我在Linux(Ubuntu12.04,gcc 4.6.3)上,试图按照我的意愿修改dlopen/close,以便制作一个基于插件的应用程序,在必要时(例如,如果重新编译)可以重新加载插件 基本原理很简单:打开插件;使用它,跟踪所有正在使用的符号。当需要重新加载时,清除所有符号并关闭插件 我创建了一个简单的演示应用程序“test.cpp”:C++ 如何知道进程是否真正使用dlclose()ed库完成了?,c++,linux,plugins,g++,dlopen,C++,Linux,Plugins,G++,Dlopen,我在Linux(Ubuntu12.04,gcc 4.6.3)上,试图按照我的意愿修改dlopen/close,以便制作一个基于插件的应用程序,在必要时(例如,如果重新编译)可以重新加载插件 基本原理很简单:打开插件;使用它,跟踪所有正在使用的符号。当需要重新加载时,清除所有符号并关闭插件 我创建了一个简单的演示应用程序“test.cpp”: #include <dlfcn.h> #include <iostream> using namespace std; int ma
#include <dlfcn.h>
#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
if (argc > 1)
{
void* h = dlopen(argv[1], RTLD_NOW|RTLD_LOCAL);
if (!h)
{
cerr << "ERROR: " << dlerror() << endl;
return 1;
}
cin.get();
if (dlclose(h))
{
cerr << "ERROR: " << dlerror() << endl;
return 2;
}
cin.get();
}
return 0;
}
要创建可以作为参数传递给上述代码的普通库,请使用:
touch libtest.cpp && g++ -rdynamic -shared libtest.cpp -o libtest.so
然后运行以下命令:
./test ./libtest.so
问题就在这里;如果在按[Enter]一次后(即加载并假定卸载库之后),您运行“pmap”检查“test”中加载了哪些库,它将告诉您libtest.so仍然存在!现在,尽管dlclose()返回了有效的值,并且没有合理的方法表明引用计数在此之前已经超过1(可以通过尝试第二个dlclose()来验证这一点-它将给出一个错误返回,表明它已经关闭)
因此,要么Linux从未卸载dlopen()库(与文档相反),要么“pmap”是错误的。如果是后者,是否有更可靠的方法来确定库是否仍在加载?我没有观察到与您使用以下程序相同的情况:
// file soq.c
#include <dlfcn.h>
#include <iostream>
#include <cstdio>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
using namespace std;
int main(int argc, char** argv)
{
char cmd[60];
snprintf(cmd, sizeof(cmd), "pmap %d", getpid());
if (argc > 1)
{
void* h = dlopen(argv[1], RTLD_NOW|RTLD_LOCAL);
if (!h)
{
cerr << "ERROR: " << dlerror() << endl;
return 1;
}
cerr << "after dlopen " << argv[1] << endl;
system(cmd);
cin.get();
if (dlclose(h))
{
cerr << "ERROR: " << dlerror() << endl;
return 2;
}
cin.get();
cerr << "after close " << argv[1] << endl;
system(cmd);
}
return 0;
}
因此,您确实错误地运行了pmap
顺便说一下,正如我的示例所示,您可以在实践中避免任何dlclose
-ing。实际上,不打扰dlclose只意味着地址空间泄漏很小,在实践中并不是什么大问题。(您可以dlopen
100万个不同的共享对象,而不会造成太大伤害)
并且要知道何时卸载一个共享对象,使用你的代码“>析构函数”的函数“DeCuffs-D插件(例如C++中静态数据的析构函数,或者在C代码中),因为它们是从卸载<代码> dLCONCEN/code >中调用的。
// file soq.c
#include <dlfcn.h>
#include <iostream>
#include <cstdio>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
using namespace std;
int main(int argc, char** argv)
{
char cmd[60];
snprintf(cmd, sizeof(cmd), "pmap %d", getpid());
if (argc > 1)
{
void* h = dlopen(argv[1], RTLD_NOW|RTLD_LOCAL);
if (!h)
{
cerr << "ERROR: " << dlerror() << endl;
return 1;
}
cerr << "after dlopen " << argv[1] << endl;
system(cmd);
cin.get();
if (dlclose(h))
{
cerr << "ERROR: " << dlerror() << endl;
return 2;
}
cin.get();
cerr << "after close " << argv[1] << endl;
system(cmd);
}
return 0;
}
% ./soq ./libempty.so
./soq ./libempty.so
after dlopen ./libempty.so
5276: ./soq ./libempty.so
0000000000400000 8K r-x-- /home/basile/tmp/soq
0000000000601000 4K rw--- /home/basile/tmp/soq
0000000001b4d000 132K rw--- [ anon ]
00007f1dbfd01000 4K r-x-- /home/basile/tmp/libempty.so
00007f1dbfd02000 2044K ----- /home/basile/tmp/libempty.so
00007f1dbff01000 4K rw--- /home/basile/tmp/libempty.so
00007f1dbff02000 1524K r-x-- /lib/x86_64-linux-gnu/libc-2.13.so
00007f1dc007f000 2048K ----- /lib/x86_64-linux-gnu/libc-2.13.so
00007f1dc027f000 16K r---- /lib/x86_64-linux-gnu/libc-2.13.so
00007f1dc0283000 4K rw--- /lib/x86_64-linux-gnu/libc-2.13.so
00007f1dc0284000 20K rw--- [ anon ]
00007f1dc0289000 84K r-x-- /lib/x86_64-linux-gnu/libgcc_s.so.1
00007f1dc029e000 2048K ----- /lib/x86_64-linux-gnu/libgcc_s.so.1
00007f1dc049e000 4K rw--- /lib/x86_64-linux-gnu/libgcc_s.so.1
00007f1dc049f000 516K r-x-- /lib/x86_64-linux-gnu/libm-2.13.so
00007f1dc0520000 2044K ----- /lib/x86_64-linux-gnu/libm-2.13.so
00007f1dc071f000 4K r---- /lib/x86_64-linux-gnu/libm-2.13.so
00007f1dc0720000 4K rw--- /lib/x86_64-linux-gnu/libm-2.13.so
00007f1dc0721000 928K r-x-- /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17
00007f1dc0809000 2048K ----- /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17
00007f1dc0a09000 32K r---- /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17
00007f1dc0a11000 8K rw--- /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17
00007f1dc0a13000 84K rw--- [ anon ]
00007f1dc0a28000 8K r-x-- /lib/x86_64-linux-gnu/libdl-2.13.so
00007f1dc0a2a000 2048K ----- /lib/x86_64-linux-gnu/libdl-2.13.so
00007f1dc0c2a000 4K r---- /lib/x86_64-linux-gnu/libdl-2.13.so
00007f1dc0c2b000 4K rw--- /lib/x86_64-linux-gnu/libdl-2.13.so
00007f1dc0c2c000 128K r-x-- /lib/x86_64-linux-gnu/ld-2.13.so
00007f1dc0e1c000 20K rw--- [ anon ]
00007f1dc0e49000 8K rw--- [ anon ]
00007f1dc0e4b000 4K r---- /lib/x86_64-linux-gnu/ld-2.13.so
00007f1dc0e4c000 4K rw--- /lib/x86_64-linux-gnu/ld-2.13.so
00007f1dc0e4d000 4K rw--- [ anon ]
00007fff076c3000 132K rw--- [ stack ]
00007fff077b4000 4K r-x-- [ anon ]
ffffffffff600000 4K r-x-- [ anon ]
total 15984K
after close ./libempty.so
5276: ./soq ./libempty.so
0000000000400000 8K r-x-- /home/basile/tmp/soq
0000000000601000 4K rw--- /home/basile/tmp/soq
0000000001b4d000 132K rw--- [ anon ]
00007f1dbff02000 1524K r-x-- /lib/x86_64-linux-gnu/libc-2.13.so
00007f1dc007f000 2048K ----- /lib/x86_64-linux-gnu/libc-2.13.so
00007f1dc027f000 16K r---- /lib/x86_64-linux-gnu/libc-2.13.so
00007f1dc0283000 4K rw--- /lib/x86_64-linux-gnu/libc-2.13.so
00007f1dc0284000 20K rw--- [ anon ]
00007f1dc0289000 84K r-x-- /lib/x86_64-linux-gnu/libgcc_s.so.1
00007f1dc029e000 2048K ----- /lib/x86_64-linux-gnu/libgcc_s.so.1
00007f1dc049e000 4K rw--- /lib/x86_64-linux-gnu/libgcc_s.so.1
00007f1dc049f000 516K r-x-- /lib/x86_64-linux-gnu/libm-2.13.so
00007f1dc0520000 2044K ----- /lib/x86_64-linux-gnu/libm-2.13.so
00007f1dc071f000 4K r---- /lib/x86_64-linux-gnu/libm-2.13.so
00007f1dc0720000 4K rw--- /lib/x86_64-linux-gnu/libm-2.13.so
00007f1dc0721000 928K r-x-- /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17
00007f1dc0809000 2048K ----- /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17
00007f1dc0a09000 32K r---- /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17
00007f1dc0a11000 8K rw--- /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17
00007f1dc0a13000 84K rw--- [ anon ]
00007f1dc0a28000 8K r-x-- /lib/x86_64-linux-gnu/libdl-2.13.so
00007f1dc0a2a000 2048K ----- /lib/x86_64-linux-gnu/libdl-2.13.so
00007f1dc0c2a000 4K r---- /lib/x86_64-linux-gnu/libdl-2.13.so
00007f1dc0c2b000 4K rw--- /lib/x86_64-linux-gnu/libdl-2.13.so
00007f1dc0c2c000 128K r-x-- /lib/x86_64-linux-gnu/ld-2.13.so
00007f1dc0e1c000 20K rw--- [ anon ]
00007f1dc0e48000 12K rw--- [ anon ]
00007f1dc0e4b000 4K r---- /lib/x86_64-linux-gnu/ld-2.13.so
00007f1dc0e4c000 4K rw--- /lib/x86_64-linux-gnu/ld-2.13.so
00007f1dc0e4d000 4K rw--- [ anon ]
00007fff076c3000 132K rw--- [ stack ]
00007fff077b4000 4K r-x-- [ anon ]
ffffffffff600000 4K r-x-- [ anon ]
total 13936K