This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Leakage from initialization of pair<..., string>


On Thu, Jul 08, 2004 at 12:51:41AM -0500, Benjamin Kosnik wrote:
> I'm unable to reproduce this, on x86/linux. I've looked at this with
> valgrind, with and without GLIBCXX_FORCE_NEW, and see no leaks.

I tested it too, using libcwd.  No leaks.

Imho, the memory allocated is freed as part of the destruction of
global objects.

Here is my test program (with libcwd specific code that allows one
to do memory leak testing):

-----------------------------
#include "sys.h"
#include <memory> 
#include <string> 
#include "debug.h"

typedef std::pair<unsigned, std::string> uint_str_t; 
std::pair<unsigned, std::string>  g_key_id_name_pairs[] = { 
    uint_str_t(64, "@"), 
    uint_str_t(65, "A"), 
    uint_str_t(66, "B") 
}; 

#if defined(CWDEBUG) && CWDEBUG_ALLOC
#include <libcw/memleak.h>

// This is actually part of libcw
static libcwd::ooam_filter_ct* S_memleak_filter;

libcwd::ooam_filter_ct& memleak_filter(void)
{
  if (!S_memleak_filter)
  {
    using namespace libcwd;
    LIBCWD_TSD_DECLARATION;
    _private_::set_alloc_checking_off(LIBCWD_TSD);
    S_memleak_filter = new libcwd::ooam_filter_ct;
    _private_::set_alloc_checking_on(LIBCWD_TSD);
  }
  return *S_memleak_filter;
}

void set_memleak_filter(libcwd::ooam_format_t flags)
{
  memleak_filter().set_flags(flags);
}

static void test_memleak(void*)
{
  int memblocks = 0;
  if (libcwd::mem_blocks() > 0)
  {
    if (!libcw::debug::channels::dc::malloc.is_on())
      libcw::debug::channels::dc::malloc.on();
    if (!S_memleak_filter)
      set_memleak_filter(libcwd::show_objectfile|libcwd::show_function);
    memblocks = libcwd::list_allocations_on(libcwd::libcw_do, *S_memleak_filter);
  }
  if (!memblocks)
    Dout(dc::malloc, "No memory leaks.");
  else
    Dout(dc::warning, "Memory leak detected!");
}

// Hook in an 'atexit' before any other __cxa_atexit calls.
// This causes test_memleak to be called after all global objects are destructed.
extern "C" { int __cxa_atexit(void (*func) (void *), void *arg, void *d); }
typedef __typeof__(&__cxa_atexit) __cxa_atexit_type;
static __cxa_atexit_type real___cxa_atexit;
int __cxa_atexit(void (*func)(void*), void* arg, void* d)
{
  if (!real___cxa_atexit)
  {
    real___cxa_atexit = (__cxa_atexit_type)dlsym(RTLD_NEXT, "__cxa_atexit");
    real___cxa_atexit(test_memleak, NULL, d);
  }
  return real___cxa_atexit(func, arg, d);
}
// End of libcw code.

extern "C" void __libc_freeres(void);
#endif

int main() 
{ 
#ifdef CWDEBUG
#if CWDEBUG_ALLOC
  // Cause exit() to free memory of the C library.
  // See http://gcc.gnu.org/onlinedocs/libstdc++/debug.html#mem
  extern void* __dso_handle __attribute__ ((__weak__));
  __cxa_atexit((void (*)(void*)) __libc_freeres, NULL, &__dso_handle ? __dso_handle : NULL);
  libcwd::make_exit_function_list_invisible();
#endif
  ForAllDebugChannels(while(!debugChannel.is_on()) debugChannel.on()); 
  Debug(libcw_do.on());
  Debug(list_channels_on(libcw_do));
#endif
  Dout(dc::notice, "Leaving main()");
} 
---------------------------


Output:

/usr/src/libcwd/test>$CXX -v
Reading specs from /usr/src/GNU/install/bin/../lib/gcc/i686-redhat-linux/3.5.0/specs
Configured with: /usr/src/gcc/gcc-cvs-3.5/configure --prefix=/usr/local/gcc-cvs-3.5 --enable-shared --with-gnu-as --with-gnu-ld --enable-languages=c++ --enable-debug --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --host=i686-redhat-linux
Thread model: posix
gcc version 3.5.0 20040530 (experimental)


/usr/src/libcwd/test>$CXX -g -DCWDEBUG -I. -I$INSTALL_PREFIX/include test.cc -L$INSTALL_PREFIX/lib -Wl,-rpath,$INSTALL_PREFIX/lib -lcwd
/usr/src/libcwd/test>a.out
BFD     : Enabled
CUSTOM  : Enabled
DEBUG   : Enabled
MALLOC  : Enabled
NOTICE  : Enabled
SYSTEM  : Enabled
WARNING : Enabled
NOTICE  : Leaving main()
MALLOC  : delete 0x8059688      new_allocator.h:81   <unknown type>; (sz = 14)
MALLOC  : delete 0x8101cc8      new_allocator.h:81   <unknown type>; (sz = 14)
MALLOC  : delete 0x80500b8      new_allocator.h:81   <unknown type>; (sz = 14)
MALLOC  : No memory leaks.

-- 
Carlo Wood <carlo@alinoe.com>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]