I'm experimenting with shared libraries to build a modularized program. This is my small test that exhibits the crappy "still reachable" messages in 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;
};
This is the interface of a "Module", all modules shall inherit from that, implementing their own version of foo
.
An actual implementation:
// 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;
}
And finally, this is how I use it (hardcoded string for demo only):
#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);
}
I compile with 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
This is my output for 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)
Question: Is it my fault or do I have to ignore these error?