[zeromq-dev] memory leak in zmq2
Martin Sustrik
sustrik at 250bpm.com
Thu Nov 26 12:04:24 CET 2009
Hi Jon,
I've applied the fix (and moved it to message_ready function as
discussed off-list). GIT rev. 8d85638
I've added you to the contributor list :)
Martin
> I found the following memory leak for non VSM messages see below. with these
> test programs on both solaris /dbx and linux / valgrind ( I also have solaris
> dbx trace but it's not worth posting as it only shows the same):-
>
> in summary on the server after the response message has been sent down the zmq
> socket on it's way to the io thread, it gets copied into the ypipe and then
> zmq_msg_init is called, this ensures it's not deleted in the app thread.
>
> however after being retrieved into the zmq_encoder for the bytes to be written
> to the buffer for io, this message appears to never be released. i have added
> a call to zmq_msg_close at what i think is an appriopriate point.
>
> after fix valgrind reports
> .....
> --19337-- supp: 25 dl-hack3-1
> ==19337== malloc/free: in use at exit: 0 bytes in 0 blocks.
> ==19337== malloc/free: 558 allocs, 558 frees, 136,155 bytes allocated.
> ==19337==
> .....
>
>
> there is a git diff below
>
>
> cheers
>
> jon
> ps an entry in the contrib file would be nice. I've spent hours tracking this
> down ;-)
>
> diff --git a/src/zmq_encoder.cpp b/src/zmq_encoder.cpp
> index 44b919b..7bc8d8e 100644
> --- a/src/zmq_encoder.cpp
> +++ b/src/zmq_encoder.cpp
> @@ -45,6 +45,7 @@ bool zmq::zmq_encoder_t::size_ready ()
> // Write message body into the buffer.
> next_step (zmq_msg_data (&in_progress), zmq_msg_size (&in_progress),
> &zmq_encoder_t::message_ready, false);
> + zmq_msg_close(&in_progress);
> return true;
> }
>
>
>
>
> --client
> // zmq
> #include <zmq.hpp>
>
> int main()
> {
>
> zmq::context_t ctx (1, 1);
>
> zmq::socket_t s (ctx, ZMQ_REQ);
>
> s.connect ("tcp://127.0.0.1:43210");
>
> for (int i = 0 ; i < 1000 ; ++i)
> {
> zmq::message_t request;
> s.send(request);
>
> zmq::message_t response;
> s.recv(&response);
>
> }
> return 0;
>
> }
>
> --server
> // zmq
> #include <zmq.hpp>
>
> int main()
> {
>
> // to do configurable
> zmq::context_t ctx (1, 1);
> zmq::socket_t s (ctx, ZMQ_REP);
> // to do configurable
> s.bind ("tcp://lo:43210");
>
> for (int i = 0 ; i < 1000 ; ++i)
> {
> zmq::message_t request;
> s.recv(&request);
>
> zmq::message_t response(40);
> s.send(response);
>
> }
> return 0;
>
> }
>
>
>
>
> jon at ubiq:~$ valgrind --tool=memcheck --leak-check=full -v ./zmqserver
> ==2007== Memcheck, a memory error detector.
> ==2007== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al.
> ==2007== Using LibVEX rev 1804, a library for dynamic binary translation.
> ==2007== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.
> ==2007== Using valgrind-3.3.0-Debian, a dynamic binary instrumentation
> framework.
> ==2007== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al.
> ==2007==
> --2007-- Command line
> --2007-- ./zmqserver
> --2007-- Startup, with flags:
> --2007-- --suppressions=/usr/lib/valgrind/debian-libc6-dbg.supp
> --2007-- --tool=memcheck
> --2007-- --leak-check=full
> --2007-- -v
> --2007-- Contents of /proc/version:
> --2007-- Linux version 2.6.24-24-generic (buildd at rothera) (gcc version 4.2.4
> (Ubuntu 4.2.4-1ubuntu4)) #1 SMP Wed Apr 15 15:54:25 UTC 2009
> --2007-- Arch and hwcaps: X86, x86-sse1
> --2007-- Page sizes: currently 4096, max supported 4096
> --2007-- Valgrind library directory: /usr/lib/valgrind
> --2007-- Reading syms from /lib/ld-2.7.so (0x4000000)
> --2007-- Reading debug info from /lib/ld-2.7.so...
> --2007-- ... CRC mismatch (computed aa5c1346 wanted 05177b25)
> --2007-- Reading debug info from /usr/lib/debug/lib/ld-2.7.so...
> --2007-- Reading syms from /home/jon/zmqserver (0x8048000)
> --2007-- Reading syms from /usr/lib/valgrind/x86-linux/memcheck (0x38000000)
> --2007-- object doesn't have a dynamic symbol table
> --2007-- Reading suppressions file: /usr/lib/valgrind/debian-libc6-dbg.supp
> --2007-- Reading suppressions file: /usr/lib/valgrind/default.supp
> --2007-- REDIR: 0x4014fe0 (index) redirected to 0x3802a393
> (vgPlain_x86_linux_REDIR_FOR_index)
> --2007-- Reading syms from /usr/lib/valgrind/x86-linux/vgpreload_core.so
> (0x401D000)
> --2007-- Reading syms from /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so
> (0x401F000)
> ==2007== WARNING: new redirection conflicts with existing -- ignoring it
> --2007-- new: 0x04014fe0 (index ) R-> 0x04022830 index
> --2007-- REDIR: 0x40151b0 (strlen) redirected to 0x40229f0 (strlen)
> --2007-- Reading syms from /sw/release/zmq2/lib/libzmq.so.0.0.0 (0x4027000)
> --2007-- Reading syms from /usr/lib/libstdc++.so.6.0.9 (0x4072000)
> --2007-- Reading debug info from /usr/lib/libstdc++.so.6.0.9...
> --2007-- ... CRC mismatch (computed b24bea06 wanted 69349987)
> --2007-- object doesn't have a symbol table
> --2007-- Reading syms from /usr/lib/debug/libm-2.7.so (0x4165000)
> --2007-- Reading syms from /lib/libgcc_s.so.1 (0x418A000)
> --2007-- Reading debug info from /lib/libgcc_s.so.1...
> --2007-- ... CRC mismatch (computed f32b6bb2 wanted ef5e2665)
> --2007-- object doesn't have a symbol table
> --2007-- Reading syms from /usr/lib/debug/libc-2.7.so (0x4195000)
> --2007-- Reading syms from /lib/libuuid.so.1.2 (0x42CE000)
> --2007-- Reading debug info from /lib/libuuid.so.1.2...
> --2007-- ... CRC mismatch (computed 51c9529c wanted 8b057812)
> --2007-- object doesn't have a symbol table
> --2007-- Reading syms from /usr/lib/debug/libpthread-2.7.so (0x42D3000)
> --2007-- REDIR: 0x42047a0 (memset) redirected to 0x4022d50 (memset)
> --2007-- REDIR: 0x4204c90 (memcpy) redirected to 0x4023aa0 (memcpy)
> --2007-- REDIR: 0x4203b50 (rindex) redirected to 0x4022710 (rindex)
> --2007-- REDIR: 0x412b420 (operator new(unsigned)) redirected to 0x4022230
> (operator new(unsigned))
> --2007-- REDIR: 0x4204700 (memmove) redirected to 0x4022da0 (memmove)
> --2007-- REDIR: 0x4129af0 (operator delete(void*)) redirected to 0x4021280
> (operator delete(void*))
> --2007-- REDIR: 0x412b560 (operator new[](unsigned)) redirected to 0x4021eb0
> (operator new[](unsigned))
> --2007-- REDIR: 0x42000e0 (calloc) redirected to 0x4020b70 (calloc)
> --2007-- REDIR: 0x4203780 (strlen) redirected to 0x40229d0 (strlen)
> --2007-- REDIR: 0x42030a0 (index) redirected to 0x4022800 (index)
> --2007-- REDIR: 0x42003f0 (malloc) redirected to 0x4021a50 (malloc)
> --2007-- REDIR: 0x4204800 (mempcpy) redirected to 0x4023490 (mempcpy)
> --2007-- REDIR: 0x41fe870 (free) redirected to 0x40215f0 (free)
> --2007-- REDIR: 0x4203210 (strcmp) redirected to 0x4022aa0 (strcmp)
> ==2007== Thread 2:
> ==2007== Syscall param socketcall.send(msg) points to uninitialised byte(s)
> ==2007== at 0x425BC2E: send (in /usr/lib/debug/libc-2.7.so)
> ==2007== by 0x404B267: zmq::zmq_engine_t::out_event() (zmq_engine.cpp:125)
> ==2007== by 0x403A1B3: zmq::epoll_t::loop() (epoll.cpp:192)
> ==2007== by 0x403A2FC: zmq::epoll_t::worker_routine(void*) (epoll.cpp:209)
> ==2007== by 0x40482F6: zmq::thread_t::thread_routine(void*) (thread.cpp:99)
> ==2007== by 0x42D7FD9: start_thread (pthread_create.c:297)
> ==2007== by 0x425A92D: clone (in /usr/lib/debug/libc-2.7.so)
> ==2007== Address 0x42ee309 is 1 bytes inside a block of size 8,192 alloc'd
> ==2007== at 0x4021AB8: malloc (vg_replace_malloc.c:207)
> ==2007== by 0x404B8FF: zmq::zmq_engine_t::zmq_engine_t(zmq::io_thread_t*,
> int) (zmq_engine.cpp:38)
> ==2007== by 0x404C616:
> zmq::zmq_listener_init_t::zmq_listener_init_t(zmq::io_thread_t*,
> zmq::socket_base_t*, int, zmq::options_t const&) (zmq_listener_init.cpp:32)
> ==2007== by 0x404BC8A: zmq::zmq_listener_t::in_event()
> (zmq_listener.cpp:68)
> ==2007== by 0x403A1E0: zmq::epoll_t::loop() (epoll.cpp:196)
> ==2007== by 0x403A2FC: zmq::epoll_t::worker_routine(void*) (epoll.cpp:209)
> ==2007== by 0x40482F6: zmq::thread_t::thread_routine(void*) (thread.cpp:99)
> ==2007== by 0x42D7FD9: start_thread (pthread_create.c:297)
> ==2007== by 0x425A92D: clone (in /usr/lib/debug/libc-2.7.so)
> ==2007==
> ==2007== Syscall param socketcall.send(msg) points to uninitialised byte(s)
> ==2007== at 0x425BC2E: send (in /usr/lib/debug/libc-2.7.so)
> ==2007== by 0x404B267: zmq::zmq_engine_t::out_event() (zmq_engine.cpp:125)
> ==2007== by 0x404B210: zmq::zmq_engine_t::revive() (zmq_engine.cpp:145)
> ==2007== by 0x404247F: zmq::session_t::revive(zmq::reader_t*)
> (session.cpp:122)
> ==2007== by 0x403D64B: zmq::reader_t::process_revive() (pipe.cpp:88)
> ==2007== by 0x403C5FE: zmq::object_t::process_command(zmq::command_t&)
> (object.cpp:66)
> ==2007== by 0x403B52B: zmq::io_thread_t::in_event() (io_thread.cpp:83)
> ==2007== by 0x403A1E0: zmq::epoll_t::loop() (epoll.cpp:196)
> ==2007== by 0x403A2FC: zmq::epoll_t::worker_routine(void*) (epoll.cpp:209)
> ==2007== by 0x40482F6: zmq::thread_t::thread_routine(void*) (thread.cpp:99)
> ==2007== by 0x42D7FD9: start_thread (pthread_create.c:297)
> ==2007== by 0x425A92D: clone (in /usr/lib/debug/libc-2.7.so)
> ==2007== Address 0x42ee309 is 1 bytes inside a block of size 8,192 alloc'd
> ==2007== at 0x4021AB8: malloc (vg_replace_malloc.c:207)
> ==2007== by 0x404B8FF: zmq::zmq_engine_t::zmq_engine_t(zmq::io_thread_t*,
> int) (zmq_engine.cpp:38)
> ==2007== by 0x404C616:
> zmq::zmq_listener_init_t::zmq_listener_init_t(zmq::io_thread_t*,
> zmq::socket_base_t*, int, zmq::options_t const&) (zmq_listener_init.cpp:32)
> ==2007== by 0x404BC8A: zmq::zmq_listener_t::in_event()
> (zmq_listener.cpp:68)
> ==2007== by 0x403A1E0: zmq::epoll_t::loop() (epoll.cpp:196)
> ==2007== by 0x403A2FC: zmq::epoll_t::worker_routine(void*) (epoll.cpp:209)
> ==2007== by 0x40482F6: zmq::thread_t::thread_routine(void*) (thread.cpp:99)
> ==2007== by 0x42D7FD9: start_thread (pthread_create.c:297)
> ==2007== by 0x425A92D: clone (in /usr/lib/debug/libc-2.7.so)
> --2007-- REDIR: 0x4129b50 (operator delete[](void*)) redirected to 0x4020e60
> (operator delete[](void*))
> ==2007==
> ==2007== ERROR SUMMARY: 1000 errors from 2 contexts (suppressed: 25 from 1)
> ==2007==
> ==2007== 1 errors in context 1 of 2:
> ==2007== Syscall param socketcall.send(msg) points to uninitialised byte(s)
> ==2007== at 0x425BC2E: send (in /usr/lib/debug/libc-2.7.so)
> ==2007== by 0x404B267: zmq::zmq_engine_t::out_event() (zmq_engine.cpp:125)
> ==2007== by 0x403A1B3: zmq::epoll_t::loop() (epoll.cpp:192)
> ==2007== by 0x403A2FC: zmq::epoll_t::worker_routine(void*) (epoll.cpp:209)
> ==2007== by 0x40482F6: zmq::thread_t::thread_routine(void*) (thread.cpp:99)
> ==2007== by 0x42D7FD9: start_thread (pthread_create.c:297)
> ==2007== by 0x425A92D: clone (in /usr/lib/debug/libc-2.7.so)
> ==2007== Address 0x42ee309 is 1 bytes inside a block of size 8,192 alloc'd
> ==2007== at 0x4021AB8: malloc (vg_replace_malloc.c:207)
> ==2007== by 0x404B8FF: zmq::zmq_engine_t::zmq_engine_t(zmq::io_thread_t*,
> int) (zmq_engine.cpp:38)
> ==2007== by 0x404C616:
> zmq::zmq_listener_init_t::zmq_listener_init_t(zmq::io_thread_t*,
> zmq::socket_base_t*, int, zmq::options_t const&) (zmq_listener_init.cpp:32)
> ==2007== by 0x404BC8A: zmq::zmq_listener_t::in_event()
> (zmq_listener.cpp:68)
> ==2007== by 0x403A1E0: zmq::epoll_t::loop() (epoll.cpp:196)
> ==2007== by 0x403A2FC: zmq::epoll_t::worker_routine(void*) (epoll.cpp:209)
> ==2007== by 0x40482F6: zmq::thread_t::thread_routine(void*) (thread.cpp:99)
> ==2007== by 0x42D7FD9: start_thread (pthread_create.c:297)
> ==2007== by 0x425A92D: clone (in /usr/lib/debug/libc-2.7.so)
> ==2007==
> ==2007== 999 errors in context 2 of 2:
> ==2007== Syscall param socketcall.send(msg) points to uninitialised byte(s)
> ==2007== at 0x425BC2E: send (in /usr/lib/debug/libc-2.7.so)
> ==2007== by 0x404B267: zmq::zmq_engine_t::out_event() (zmq_engine.cpp:125)
> ==2007== by 0x404B210: zmq::zmq_engine_t::revive() (zmq_engine.cpp:145)
> ==2007== by 0x404247F: zmq::session_t::revive(zmq::reader_t*)
> (session.cpp:122)
> ==2007== by 0x403D64B: zmq::reader_t::process_revive() (pipe.cpp:88)
> ==2007== by 0x403C5FE: zmq::object_t::process_command(zmq::command_t&)
> (object.cpp:66)
> ==2007== by 0x403B52B: zmq::io_thread_t::in_event() (io_thread.cpp:83)
> ==2007== by 0x403A1E0: zmq::epoll_t::loop() (epoll.cpp:196)
> ==2007== by 0x403A2FC: zmq::epoll_t::worker_routine(void*) (epoll.cpp:209)
> ==2007== by 0x40482F6: zmq::thread_t::thread_routine(void*) (thread.cpp:99)
> ==2007== by 0x42D7FD9: start_thread (pthread_create.c:297)
> ==2007== by 0x425A92D: clone (in /usr/lib/debug/libc-2.7.so)
> ==2007== Address 0x42ee309 is 1 bytes inside a block of size 8,192 alloc'd
> ==2007== at 0x4021AB8: malloc (vg_replace_malloc.c:207)
> ==2007== by 0x404B8FF: zmq::zmq_engine_t::zmq_engine_t(zmq::io_thread_t*,
> int) (zmq_engine.cpp:38)
> ==2007== by 0x404C616:
> zmq::zmq_listener_init_t::zmq_listener_init_t(zmq::io_thread_t*,
> zmq::socket_base_t*, int, zmq::options_t const&) (zmq_listener_init.cpp:32)
> ==2007== by 0x404BC8A: zmq::zmq_listener_t::in_event()
> (zmq_listener.cpp:68)
> ==2007== by 0x403A1E0: zmq::epoll_t::loop() (epoll.cpp:196)
> ==2007== by 0x403A2FC: zmq::epoll_t::worker_routine(void*) (epoll.cpp:209)
> ==2007== by 0x40482F6: zmq::thread_t::thread_routine(void*) (thread.cpp:99)
> ==2007== by 0x42D7FD9: start_thread (pthread_create.c:297)
> ==2007== by 0x425A92D: clone (in /usr/lib/debug/libc-2.7.so)
> --2007--
> --2007-- supp: 25 dl-hack3-1
> ==2007==
> ==2007== IN SUMMARY: 1000 errors from 2 contexts (suppressed: 25 from 1)
> ==2007==
> ==2007== malloc/free: in use at exit: 55,944 bytes in 999 blocks.
> ==2007== malloc/free: 1,558 allocs, 559 frees, 192,155 bytes allocated.
> ==2007==
> ==2007== searching for pointers to 999 not-freed blocks.
> ==2007== checked 124,680 bytes.
> ==2007==
> ==2007== Thread 1:
> ==2007==
> ==2007== 55,944 bytes in 999 blocks are definitely lost in loss record 1 of 1
> ==2007== at 0x4021AB8: malloc (vg_replace_malloc.c:207)
> ==2007== by 0x404956A: zmq_msg_init_size (zmq.cpp:94)
> ==2007== by 0x8048ED8: zmq::message_t::message_t(unsigned)
> (in /home/jon/zmqserver)
> ==2007== by 0x8048B48: main (in /home/jon/zmqserver)
> ==2007==
> ==2007== LEAK SUMMARY:
> ==2007== definitely lost: 55,944 bytes in 999 blocks.
> ==2007== possibly lost: 0 bytes in 0 blocks.
> ==2007== still reachable: 0 bytes in 0 blocks.
> ==2007== suppressed: 0 bytes in 0 blocks.
> --2007-- memcheck: sanity checks: 8 cheap, 2 expensive
> --2007-- memcheck: auxmaps: 0 auxmap entries (0k, 0M) in use
> --2007-- memcheck: auxmaps_L1: 0 searches, 0 cmps, ratio 0:10
> --2007-- memcheck: auxmaps_L2: 0 searches, 0 nodes
> --2007-- memcheck: SMs: n_issued = 20 (320k, 0M)
> --2007-- memcheck: SMs: n_deissued = 0 (0k, 0M)
> --2007-- memcheck: SMs: max_noaccess = 65535 (1048560k, 1023M)
> --2007-- memcheck: SMs: max_undefined = 0 (0k, 0M)
> --2007-- memcheck: SMs: max_defined = 162 (2592k, 2M)
> --2007-- memcheck: SMs: max_non_DSM = 20 (320k, 0M)
> --2007-- memcheck: max sec V bit nodes: 0 (0k, 0M)
> --2007-- memcheck: set_sec_vbits8 calls: 0 (new: 0, updates: 0)
> --2007-- memcheck: max shadow mem size: 624k, 0M
> --2007-- translate: fast SP updates identified: 5,413 ( 89.1%)
> --2007-- translate: generic_known SP updates identified: 419 ( 6.9%)
> --2007-- translate: generic_unknown SP updates identified: 239 ( 3.9%)
> --2007-- tt/tc: 17,694 tt lookups requiring 20,056 probes
> --2007-- tt/tc: 17,694 fast-cache updates, 3 flushes
> --2007-- transtab: new 4,451 (90,565 -> 1,344,563; ratio 148:10) [0
> scs]
> --2007-- transtab: dumped 0 (0 -> ??)
> --2007-- transtab: discarded 8 (206 -> ??)
> --2007-- scheduler: 985,523 jumps (bb entries).
> --2007-- scheduler: 8/25,672 major/minor sched events.
> --2007-- sanity: 9 cheap, 2 expensive checks.
> --2007-- exectx: 769 lists, 106 contexts (avg 0 per list)
> --2007-- exectx: 3,142 searches, 3,043 full compares (968 per 1000)
> --2007-- exectx: 998 cmp2, 1,062 cmp4, 0 cmpAll
> --2007-- errormgr: 11 supplist searches, 299 comparisons during search
> --2007-- errormgr: 1,025 errlist searches, 1,078 comparisons during search
>
More information about the zeromq-dev
mailing list