【问题标题】:How to determine which dynamic library is responsible for creation of a pointer?如何确定哪个动态库负责创建指针?
【发布时间】:2015-01-06 19:20:21
【问题描述】:

假设您有一个使用 dlopen() 加载多个共享对象/动态库的程序。给定一个指向全局对象(例如静态成员变量)的指针,是否可以确定该指针分配在哪个库的边界?

【问题讨论】:

  • 使用调试器单步调试程序并观察哪个代码分配了它?
  • 我能想到的唯一方法是确保每个库都使用不同的分配器(malloc & free)。如果您可以访问符号表(dlopen 让您拥有它)并且知道它的结构,您可能可以修补导入的 malloc 符号以指向专用函数。
  • @sashoalm 问题被标记为 linux
  • 但是如果库使用非常规的分配器,那就更难了。但是,它可以帮助您区分其分配。
  • @didierc dlopen 等让符号和指针来回解析。但是当你必须从两者都开始的时候,你能不能把所有的指针都枚举出来,一一检查呢?重载 malloc 和 free 似乎是一个实用的想法,但让我们把它作为最后的手段。

标签: c++ c linux shared-objects dynamic-library


【解决方案1】:

您可以使用文件/proc/self/maps 解析进程映射并查看指针地址的边界,全局变量将位于.data.bss 段中。

示例库lib.c:

static int object;

int *
dummy(void)
{
  return &object;
}

test.c,为简单起见未处理错误:

#include <stdio.h>
#include <dlfcn.h>
#include <unistd.h>
#include <inttypes.h>
#include <assert.h>
#include <linux/limits.h>

static void which_library(void *p);

int
main(int argc, char **argv)
{
  void *handle;
  void *object;

  handle = dlopen("./lib.so", RTLD_NOW);
  assert(handle);

  object = ((int *(*)(void)) dlsym(handle, "dummy"))();
  which_library(object);
  dlclose(handle);

  return 0;
}

static void
which_library(void *p)
{
  FILE *maps;
  char buffer[49+PATH_MAX+1];

  maps = fopen("/proc/self/maps", "r");
  assert(maps);

  while(fgets(buffer, sizeof(buffer) - 1, maps)) {
    char path[PATH_MAX+1];
    uintptr_t starts;
    uintptr_t ends;

    sscanf(buffer, "%" PRIxPTR "-%" PRIxPTR " %*s %*x %*x:%*x %*d %s", &starts, &ends, path);
    if((uintptr_t)p >= starts && (uintptr_t)p < ends) {
      printf("%p => %s\n", p, path);
      break;
    }
  }

  fclose(maps);
}

测试:

$ gcc -Wall -shared lib.c -o lib.so 
$ gcc -Wall test.c -ldl
$ ./a.out 
0xb779f5f8 => /home/barakat/Desktop/lib.so
$ 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-31
    • 2018-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多