使用共享库时仍可访问内存

Memory still reachable working with shared library

本文关键字:访问 内存 共享      更新时间:2023-10-16

我正在尝试使用共享库来构建模块化程序。这是我的小测试,展示了瓦尔格林德中蹩脚的"仍然可以到达"的消息。

// 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;
};

这是"模块"的接口,所有模块都应继承自该接口,实现自己的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 二进制

这是我对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)

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

由于所有这些堆栈跟踪都不涉及您的代码,因此您确实会坚持使用它们。