我在一个使用dlopen加载的共享对象(代码)中。我想知道加载调用的标志。我无法访问加载器(代码)--例如,它可能是一个脚本解释器--但我必须使用相同的标志创建后续的dlopen调用。
我该怎么做呢?
发布于 2012-03-26 23:40:18
我认为如果没有调试器的帮助,这是不可能的。
下面是dlopen的源代码,来自latest glibc code
void *
dlopen (const char *file, int mode)
{
return __dlopen (file, mode, RETURN_ADDRESS (0));
}而__dlopen又被定义为
void *
__dlopen (const char *file, int mode DL_CALLER_DECL)
{
# ifdef SHARED
if (__builtin_expect (_dlfcn_hook != NULL, 0))
return _dlfcn_hook->dlopen (file, mode, DL_CALLER);
# endif
struct dlopen_args args;
args.file = file;
args.mode = mode;
args.caller = DL_CALLER;
# ifdef SHARED
return _dlerror_run (dlopen_doit, &args) ? NULL : args.new;
# else
if (_dlerror_run (dlopen_doit, &args))
return NULL;
__libc_register_dl_open_hook ((struct link_map *) args.new);
__libc_register_dlfcn_hook ((struct link_map *) args.new);
return args.new;
# endif
}您要查找的标志RTLD_LAZY、RTLD_NOW、RTLD_GLOBAL和RTLD_LOCAL均为ORed,并存储在mode变量中。正如你所看到的,它没有被传递回来的路径,或者类似的东西。
EDIT:正如另一个答案所示,似乎确实有一种方法可以实现你想要的东西。如果你可以不接受我的回答,我可以删除它,以帮助未来的访问者
发布于 2014-06-07 17:40:17
您可以使用下列库来代替调试器:
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
typedef void *(*orig_dlopen_type)(const char *file, int mode);
void *dlopen(const char *file, int mode)
{
fprintf(stderr, "dlopen called (mode: %d) on %s\n", mode, file);
orig_dlopen_type orig_dlopen;
orig_dlopen = (orig_dlopen_type)dlsym(RTLD_NEXT, "dlopen");
return orig_dlopen(file, mode);
}使用gcc -shared -fPIC dlopen_trace.c -o dlopen_trace.so -ldl进行编译
然后用LD_PRELOAD=dlopen_trace.so像平常一样执行你的程序。您应该在每次调用dlopen时打印一个调试行。
如果您愿意,您还可以在途中修改标志...
https://stackoverflow.com/questions/9874396
复制相似问题