2
votes

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?

1

1 Answers

5
votes

Since all these stacktraces involve none of your code, you are, indeed, stuck with them.