3
votes

I'm trying to read and write asynchronously to disk in C++ (using the posix aio library in Ubuntu 10.04), following the directions outlined here: aio tutorial. I can asynchronously read and write, but I'm afraid there is a small memory leak of some sort. My valgrind output says that there are 288 possibly lost bytes and 3,648 still reachable bytes. These numbers seem to be independent of the amount of bytes actually read from file. I cannot find where or how to eliminate this leak - and it even looks like it's a problem with the aio library. Has anyone seen this before? The full valgrind output is below. Thanks in advance.

==22330== 
==22330== HEAP SUMMARY:
==22330==     in use at exit: 3,936 bytes in 3 blocks
==22330==   total heap usage: 25 allocs, 22 frees, 15,648 bytes allocated
==22330== 
==22330== 64 bytes in 1 blocks are still reachable in loss record 1 of 3
==22330==    at 0x4C274A8: malloc (vg_replace_malloc.c:236)
==22330==    by 0x4C27522: realloc (vg_replace_malloc.c:525)
==22330==    by 0x504CAF1: __aio_enqueue_request (aio_misc.c:127)
==22330==    by 0x504D25A: aio_read (aio_read.c:30)
==22330==    by 0x406EB7: baio::read(std::string, char*, long) (baio_unix.cxx:58)
==22330==    by 0x40613E: test_read_helper(char*) (test_read.cxx:16)
==22330==    by 0x4063E1: test_read() (test_read.cxx:54)
==22330==    by 0x40664C: test_read_main(int, char**) (test_read.cxx:74)
==22330==    by 0x40959D: testlib_run_test_unit(unsigned long, int, char**) (testlib_main.cxx:116)
==22330==    by 0x4097A9: testlib_main(int, char**) (testlib_main.cxx:155)
==22330==    by 0x4060B4: main (test_driver.cxx:12)
==22330== 
==22330== 288 bytes in 1 blocks are possibly lost in loss record 2 of 3
==22330==    at 0x4C267CC: calloc (vg_replace_malloc.c:467)
==22330==    by 0x4012395: _dl_allocate_tls (dl-tls.c:300)
==22330==    by 0x4E34728: pthread_create@@GLIBC_2.2.5 (allocatestack.c:561)
==22330==    by 0x504C9A8: __aio_enqueue_request (aio_misc.h:60)
==22330==    by 0x504D25A: aio_read (aio_read.c:30)
==22330==    by 0x406EB7: baio::read(std::string, char*, long) (baio_unix.cxx:58)
==22330==    by 0x40613E: test_read_helper(char*) (test_read.cxx:16)
==22330==    by 0x4063E1: test_read() (test_read.cxx:54)
==22330==    by 0x40664C: test_read_main(int, char**) (test_read.cxx:74)
==22330==    by 0x40959D: testlib_run_test_unit(unsigned long, int, char**) (testlib_main.cxx:116)
==22330==    by 0x4097A9: testlib_main(int, char**) (testlib_main.cxx:155)
==22330==    by 0x4060B4: main (test_driver.cxx:12)
==22330== 
==22330== 3,584 bytes in 1 blocks are still reachable in loss record 3 of 3
==22330==    at 0x4C267CC: calloc (vg_replace_malloc.c:467)
==22330==    by 0x504CA27: __aio_enqueue_request (aio_misc.c:139)
==22330==    by 0x504D25A: aio_read (aio_read.c:30)
==22330==    by 0x406EB7: baio::read(std::string, char*, long) (baio_unix.cxx:58)
==22330==    by 0x40613E: test_read_helper(char*) (test_read.cxx:16)
==22330==    by 0x4063E1: test_read() (test_read.cxx:54)
==22330==    by 0x40664C: test_read_main(int, char**) (test_read.cxx:74)
==22330==    by 0x40959D: testlib_run_test_unit(unsigned long, int, char**) (testlib_main.cxx:116)
==22330==    by 0x4097A9: testlib_main(int, char**) (testlib_main.cxx:155)
==22330==    by 0x4060B4: main (test_driver.cxx:12)
==22330== 
==22330== LEAK SUMMARY:
==22330==    definitely lost: 0 bytes in 0 blocks
==22330==    indirectly lost: 0 bytes in 0 blocks
==22330==      possibly lost: 288 bytes in 1 blocks
==22330==    still reachable: 3,648 bytes in 2 blocks
==22330==         suppressed: 0 bytes in 0 blocks
1

1 Answers

2
votes

The second block looks like thread local storage associated with a library-owned thread created to handle async read(s).

==22330==    by 0x4012395: _dl_allocate_tls (dl-tls.c:300)
==22330==    by 0x4E34728: pthread_create@@GLIBC_2.2.5 (allocatestack.c:561)

The first and third look like internal structs associated with an outstanding async read.

If you can run for a sustained time with only this to worry about, my instinct would be to be grateful for small mercies. The library surely has to have some latitude to allocate persistent memory to correlate the result for an async read.