c++ - 使用共享库时内存仍然可达

标签 c++ linux shared-libraries

我正在尝试使用共享库来构建模块化程序。这是我的小测试,展示了 valgrind 中蹩脚的“仍然可达”消息。

// module.h
#pragma once

struct Module
{
   public:
      Module(){}
      virtual ~Module(){}
      virtual int foo(const int, const double) = 0;
   private:
      Module(const Module&) = delete;
      Module& operator=(const Module&) = delete;
};

这是“模块”的接口(interface),所有模块都应继承该接口(interface),实现自己的 foo 版本。

实际实现:

// module_core.cpp
#include "module.h"
#include <iostream>

struct ModuleCore : public Module
{
   int foo(const int a, const double b) override;
};

extern "C" Module* load()
{
   return new ModuleCore;
}

extern "C" void unload(Module* module)
{
   auto mc = static_cast<ModuleCore*>(module);
   delete mc;
}

int ModuleCore::foo(const int a, const double b)
{
   std::cout << __func__ << "(" << a << ", " << b / 4.0 << ");\n";
   return a;
}

最后,这就是我使用它的方式(硬编码字符串仅用于演示):

#include "module.h"
#include <dlfcn.h>

int main()
{
   auto h = dlopen("./module_core.so", RTLD_LAZY);
   Module* (*load)();
   load = (Module* (*)()) dlsym(h, "load");
   void (*unload)(Module*);
   unload = (void (*)(Module*)) dlsym(h, "unload");
   auto m = load();
   m->foo(1,2.0);
   unload(m);
   dlclose(h);
}

我用g++-4.7.3编译:

g++ -Wall -Wextra -pedantic -std=c++0x -fPIC -shared module_core.cpp -o module_core.so

g++ -Wall -Wextra -pedantic -std=c++0x src/main.cpp -ldl -o binary

这是我的 valgrind ./binary 输出:

==25095== Memcheck, a memory error detector
==25095== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==25095== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==25095== Command: ./binary
==25095== 
foo(1, 0.5);
==25095== 
==25095== HEAP SUMMARY:
==25095==     in use at exit: 5,373 bytes in 16 blocks
==25095==   total heap usage: 27 allocs, 11 frees, 7,884 bytes allocated
==25095== 
==25095== 48 bytes in 3 blocks are still reachable in loss record 1 of 6
==25095==    at 0x402C418: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==25095==    by 0x401410B: _dl_close_worker (dl-close.c:374)
==25095==    by 0x4014917: _dl_close (dl-close.c:776)
==25095==    by 0x404DDE1: dlclose_doit (dlclose.c:36)
==25095==    by 0x400F05D: _dl_catch_error (dl-error.c:177)
==25095==    by 0x404E421: _dlerror_run (dlerror.c:163)
==25095==    by 0x404DE17: dlclose (dlclose.c:47)
==25095==    by 0x406C934: (below main) (libc-start.c:260)
==25095== 
==25095== 103 bytes in 3 blocks are still reachable in loss record 2 of 6
==25095==    at 0x402C418: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==25095==    by 0x400531E: local_strdup (dl-load.c:162)
==25095==    by 0x4008700: _dl_map_object (dl-load.c:2510)
==25095==    by 0x400CE1D: openaux (dl-deps.c:63)
==25095==    by 0x40130D9: dl_open_worker (dl-open.c:265)
==25095==    by 0x400F05D: _dl_catch_error (dl-error.c:177)
==25095==    by 0x404DCCD: dlopen_doit (dlopen.c:66)
==25095==    by 0x400F05D: _dl_catch_error (dl-error.c:177)
==25095== 
==25095== 103 bytes in 3 blocks are still reachable in loss record 3 of 6
==25095==    at 0x402C418: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==25095==    by 0x400AB6A: _dl_new_object (dl-object.c:160)
==25095==    by 0x400651F: _dl_map_object_from_fd (dl-load.c:1053)
==25095==    by 0x4008448: _dl_map_object (dl-load.c:2606)
==25095==    by 0x400CE1D: openaux (dl-deps.c:63)
==25095==    by 0x40130D9: dl_open_worker (dl-open.c:265)
==25095==    by 0x400F05D: _dl_catch_error (dl-error.c:177)
==25095==    by 0x404DCCD: dlopen_doit (dlopen.c:66)
==25095==    by 0x400F05D: _dl_catch_error (dl-error.c:177)
==25095== 
==25095== 1,200 bytes in 3 blocks are still reachable in loss record 4 of 6
==25095==    at 0x402A2FB: calloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==25095==    by 0x40107D5: _dl_check_map_versions (dl-version.c:294)
==25095==    by 0x4013585: dl_open_worker (dl-open.c:271)
==25095==    by 0x400F05D: _dl_catch_error (dl-error.c:177)
==25095==    by 0x404DCCD: dlopen_doit (dlopen.c:66)
==25095==    by 0x400F05D: _dl_catch_error (dl-error.c:177)
==25095== 
==25095== 1,887 bytes in 3 blocks are still reachable in loss record 5 of 6
==25095==    at 0x402A2FB: calloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==25095==    by 0x400A930: _dl_new_object (dl-object.c:76)
==25095==    by 0x400651F: _dl_map_object_from_fd (dl-load.c:1053)
==25095==    by 0x4008448: _dl_map_object (dl-load.c:2606)
==25095==    by 0x400CE1D: openaux (dl-deps.c:63)
==25095==    by 0x40130D9: dl_open_worker (dl-open.c:265)
==25095==    by 0x400F05D: _dl_catch_error (dl-error.c:177)
==25095==    by 0x404DCCD: dlopen_doit (dlopen.c:66)
==25095==    by 0x400F05D: _dl_catch_error (dl-error.c:177)
==25095== 
==25095== 2,032 bytes in 1 blocks are still reachable in loss record 6 of 6
==25095==    at 0x402A2FB: calloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==25095==    by 0x4009470: do_lookup_x (dl-lookup.c:381)
==25095==    by 0x40099B1: _dl_lookup_symbol_x (dl-lookup.c:739)
==25095==    by 0x400B5C0: _dl_relocate_object (dl-machine.h:339)
==25095==    by 0x401332F: dl_open_worker (dl-open.c:420)
==25095==    by 0x400F05D: _dl_catch_error (dl-error.c:177)
==25095==    by 0x404DCCD: dlopen_doit (dlopen.c:66)
==25095==    by 0x400F05D: _dl_catch_error (dl-error.c:177)
==25095== 
==25095== LEAK SUMMARY:
==25095==    definitely lost: 0 bytes in 0 blocks
==25095==    indirectly lost: 0 bytes in 0 blocks
==25095==      possibly lost: 0 bytes in 0 blocks
==25095==    still reachable: 5,373 bytes in 16 blocks
==25095==         suppressed: 0 bytes in 0 blocks
==25095== 
==25095== For counts of detected and suppressed errors, rerun with: -v
==25095== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

问题:这是我的错还是我必须忽略这些错误?

最佳答案

由于所有这些堆栈跟踪都不涉及您的代码,因此您确实被它们困住了。

关于c++ - 使用共享库时内存仍然可达,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19181369/

相关文章:

node.js - npm 更新破坏了 npm

linux - QT 配置 - QFSFileEngine::currentDirectory 无法统计 (".")

linux - 如何将备用 glibc 与现有的 libstdc++ 一起使用?

shared-libraries - libltdl.so.3 : cannot open shared object file: No such file or directory in Ubuntu 14. 04

c - read() 的包装函数无法编译

c++ - matlab C 共享库 : capturing matlab function output with mxArray*/mxArray**

c++ - 同一个类中的迭代器和 const_iterator 的问题

c++ - 在模板中, "std::result_of<int&()>"中没有名为 type 的类型

c++ - 如何在 C++ 中使用 STL 排序对类中的某些值进行排序?

c++ - 什么时候重新分配 `[in,out]` 参数是可选的?