在Linux上获取C ++中加载的库列表(在运行时)

时间:2016-11-27 17:54:40

标签: c++ linux shared-libraries

如何从正在运行的C ++程序中获取所有已加载的共享库及其内存地址(开始,结束)的列表?

我正在编写一个小型崩溃报告实用程序,它可以在崩溃时输出在崩溃时的地址范围加载的库以及其他信息。以下是我用于Windows的内容:

void GetLoadedModules(std::vector<Module> &modules) {
  HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 0);
  if (snapshot != INVALID_HANDLE_VALUE) {
    MODULEENTRY32 module_entry;
    module_entry.dwSize = sizeof(module_entry);
    if (Module32First(snapshot, &module_entry)) {
      do {
        Module module(module_entry.szModule,
                      (uint32_t)module_entry.modBaseAddr,
                      module_entry.modBaseSize);
        modules.push_back(module);
        module_entry.dwSize = sizeof(module_entry);
      } while (Module32Next(snapshot, &module_entry));
    }
    CloseHandle(snapshot);
  }
}

你能在Linux上做同等的事吗?或者最好是从/proc/$pid/maps

这样的内容中读取

更新

这是我最终的结果。正如@n.m所建议的那样。在他/她的评论中,我使用dl_iterate_phdr来实现这一点:

extern const char *__progname;

int VisitModule(struct dl_phdr_info *info, size_t size, void *data) {
  std::vector<Module> *modules = reinterpret_cast<std::vector<Module> *>(data);

  const char *name = info->dlpi_name;
  if (modules->size() == 0) {
    // First visited entry is the main program.
    name = __progname;
  }

  uint32_t base_address = info->dlpi_addr;
  uint32_t total_size = 0;
  for (int i = 0; i < info->dlpi_phnum; i++) {
    total_size += info->dlpi_phdr[i].p_memsz;
  }

  Module module(name, base_address, total_size);
  modules->push_back(module);
  return 0;
}

void GetLoadedModules(std::vector<Module> &modules) {
  modules.clear();
  dl_iterate_phdr(VisitModule, reinterpret_cast<void *>(&modules));
}

0 个答案:

没有答案