【问题标题】:LD_PRELOAD with boost fileystem libraryLD_PRELOAD 与 boost 文件系统库
【发布时间】:2012-10-09 23:14:48
【问题描述】:

我正在尝试拦截 Linux 中的开放系统调用。它适用于其他库,但不适用于 boost libboost_fileystem。这是我的代码(为了便于阅读而删减了)。

#include <boost/filesystem/fstream.hpp>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <dlfcn.h>
#include <stdarg.h>
#include <stdio.h>

using namespace std;
using namespace boost::filesystem;

typedef int (*open_func_type)(const char * pathname, int flags, ...);

int open(const char *path, int flags, ...)
{
  va_list arg;
  mode_t mode = 0;
  if (flags & O_CREAT)
    {
      va_start(arg, flags);
      mode = va_arg(arg, mode_t);
      va_end(arg);
    }

  //some stuff here
  open_func_type open_func = (open_func_type) dlsym(RTLD_NEXT, "open");
  return open_func(path, flags, mode);
}

int main()
{
   boost::filesystem::fstream build_path;
   build_path.open("/tmp/test.txt", ios::in);

   //other stuff
   return 0;
}

我使用 gdb 单步执行了代码,但没有调用我的开放实现。但是执行 strace 会显示正在调用的开放系统调用。如果我调用其他调用 open 的库函数,我会看到我的实现被调用。我在这里做错了什么?我正在与 boost 库动态链接。

【问题讨论】:

  • 你不是在拦截open系统调用,你是在拦截open库函数。
  • 你也没有使用LD_PRELOAD。如果你是,这可能会起作用。
  • 嗯,它不完全是 LD_PRELOAD 和系统调用,但我认为这应该因为 LD_PRELOAD 起作用的类似原因而起作用。
  • 它不起作用,因为它没有在它试图拦截的库之前加载,也因为它没有拦截系统调用。如果它做了这两件事中的任何一件,它就会起作用。但由于它不执行其中任何一个,库仍然调用常规的open 函数,该函数调用未被拦截的系统调用。
  • 系统调用在内核中,所以我认为为了拦截它们,我们必须拦截调用它们的库调用。另外我的理解是可执行文件首先被加载,然后它的依赖关系被解析。如果您创建自己的调用 open 的动态库(而不是 boost),这件事就可以正常工作。 Boost 内部似乎使用 std::filebuf,可能这个库正在调用不同的函数,该函数又调用内核中的 open 系统调用。

标签: c++ c linux boost


【解决方案1】:

我花了一些时间来解决这个问题,发现内部 boost 调用 std::basic_filebuf open 反过来又调用 fopen。 fopen 似乎在内核中调用 open 系统调用而不调用 open 库调用(如果有人能指出原因会很好)。我截获了 fopen 呼叫,现在可以正常工作。如果使用大文件支持,还需要实现fopen64。

【讨论】:

  • 一方面,如果文件以只读方式打开,fopen 可能会调用mmap。 (参见 glibc 的 libio/iofopen.c 文件。)
猜你喜欢
  • 1970-01-01
  • 2016-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-12
  • 2020-06-12
  • 1970-01-01
相关资源
最近更新 更多