访问dlopen标志

时间:2012-03-26 14:49:17

标签: c++ c dlopen

我在一个用dlopen加载的共享对象(代码)里面。我想知道加载调用的标志。我无权访问加载程序(代码) - 例如它可能是一个脚本解释器 - 但我必须使用相同的标志创建后续的dlopen调用。

我该怎么做?

2 个答案:

答案 0 :(得分:3)

您可以使用以下库代替调试器:

#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时都应该打印一个调试行。

如果您愿意,也可以修改途中的标志......

答案 1 :(得分:0)

我认为如果没有调试器的帮助,这是不可能的。

latest glibc code开始,以下是dlopen

的源代码
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_LAZYRTLD_NOWRTLD_GLOBALRTLD_LOCAL已进行OR运算并存储在mode变量中。正如你所看到的那样,它没有传递回来的路线或类似的东西。

编辑:似乎确实有一种方法可以达到你想要的效果,如另一个答案所示。如果您可以取消接受我的回答,我可以删除它以便帮助将来的访问者