Bug 3825 - Memory leak in oneway call with an input parameter greater than 128k
Summary: Memory leak in oneway call with an input parameter greater than 128k
Status: RESOLVED FIXED
Alias: None
Product: TAO
Classification: Unclassified
Component: other (show other bugs)
Version: 1.7.6
Hardware: x86 Linux
: P3 normal
Assignee: DOC Center Support List (internal)
URL:
Depends on:
Blocks: 3773
  Show dependency tree
 
Reported: 2010-02-17 14:38 CST by Rick Marlborough
Modified: 2011-03-02 10:17 CST (History)
0 users

See Also:


Attachments
Oneway memory leak client and server test applications (2.98 KB, application/gzip)
2010-02-17 14:38 CST, Rick Marlborough
Details
Possible fix for the memory leak. (485 bytes, patch)
2011-02-25 09:19 CST, Chris Galli
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Rick Marlborough 2010-02-17 14:38:17 CST
Created attachment 1257 [details]
Oneway memory leak client and server test applications

I ran a test, source code is attached, which contains a client application making 100 oneway point to point calls to a server application.  Both the client and server applications were running on the same node. Each oneway call contains an input parameter with a size of 500k.  Each time the client application invokes the oneway call, the application's memory usage increases by 500k. I ran the client application with valgrind and here is what it detects for the memory usage: 

==15653== 52,838,400 bytes in 100 blocks are still reachable in loss record 875 of 875
==15653==    at 0x4004EA5: operator new[](unsigned, std::nothrow_t const&) (vg_replace_malloc.c:207)
==15653==    by 0x40E7D6B: ACE_Local_Memory_Pool::acquire(unsigned, unsigned&) (in /home/ACE_TAO_5.7.6/ACE_wrappers/ace/libACE.so.5.7.6)
==15653==    by 0x40D97C7: ACE_Malloc_T<ACE_Local_Memory_Pool, ACE_Thread_Mutex, ACE_Control_Block>::shared_malloc(unsigned) (in /home/ACE_TAO_5.7.6/ACE_wrappers/ace/libACE.so.5.7.6)
==15653==    by 0x40D9062: ACE_Malloc_T<ACE_Local_Memory_Pool, ACE_Thread_Mutex, ACE_Control_Block>::malloc(unsigned) (in /home/ACE_TAO_5.7.6/ACE_wrappers/ace/libACE.so.5.7.6)
==15653==    by 0x40D8CA5: ACE_Allocator_Adapter<ACE_Malloc<ACE_Local_Memory_Pool, ACE_Thread_Mutex> >::malloc(unsigned) (in /home/ACE_TAO_5.7.6/ACE_wrappers/ace/libACE.so.5.7.6)
==15653==    by 0x40F2CBD: ACE_Data_Block::ACE_Data_Block(unsigned, int, char const*, ACE_Allocator*, ACE_Lock*, unsigned long, ACE_Allocator*) (in /home/ACE_TAO_5.7.6/ACE_wrappers/ace/libACE.so.5.7.6)
==15653==    by 0x40F4116: ACE_Data_Block::clone_nocopy(unsigned long, unsigned) const (in /home/ACE_TAO_5.7.6/ACE_wrappers/ace/libACE.so.5.7.6)
==15653==    by 0x40F4096: ACE_Data_Block::clone(unsigned long) const (in /home/ACE_TAO_5.7.6/ACE_wrappers/ace/libACE.so.5.7.6)
==15653==    by 0x40F4196: ACE_Message_Block::clone(unsigned long) const (in /home/ACE_TAO_5.7.6/ACE_wrappers/ace/libACE.so.5.7.6)
==15653==    by 0x4281735: TAO_Synch_Queued_Message::copy_if_necessary(ACE_Message_Block const*) (in /home/ACE_TAO_5.7.6/ACE_wrappers/TAO/tao/libTAO.so.1.7.6)
==15653==    by 0x4296C5F: TAO_Transport::cleanup_queue(unsigned) (in /home/ACE_TAO_5.7.6/ACE_wrappers/TAO/tao/libTAO.so.1.7.6)
==15653==    by 0x429635A: TAO_Transport::drain_queue_helper(int&, iovec*, TAO::Transport::Drain_Constraints const&) (in /home/ACE_TAO_5.7.6/ACE_wrappers/TAO/tao/libTAO.so.1.7.6)
==15653==    by 0x4296738: TAO_Transport::drain_queue_i(TAO::Transport::Drain_Constraints const&) (in /home/ACE_TAO_5.7.6/ACE_wrappers/TAO/tao/libTAO.so.1.7.6)
==15653==    by 0x4295657: TAO_Transport::send_message_block_chain_i(ACE_Message_Block const*, unsigned&, TAO::Transport::Drain_Constraints const&) (in /home/ACE_TAO_5.7.6/ACE_wrappers/TAO/tao/libTAO.so.1.7.6)
==15653==    by 0x42975AB: TAO_Transport::send_asynchronous_message_i(TAO_Stub*, ACE_Message_Block const*, ACE_Time_Value*) (in /home/ACE_TAO_5.7.6/ACE_wrappers/TAO/tao/libTAO.so.1.7.6)
==15653==    by 0x4297118: TAO_Transport::send_message_shared_i(TAO_Stub*, TAO_Message_Semantics, ACE_Message_Block const*, ACE_Time_Value*) (in /home/ACE_TAO_5.7.6/ACE_wrappers/TAO/tao/libTAO.so.1.7.6)
==15653==    by 0x4294CD0: TAO_Transport::send_message_shared(TAO_Stub*, TAO_Message_Semantics, ACE_Message_Block const*, ACE_Time_Value*) (in /home/ACE_TAO_5.7.6/ACE_wrappers/TAO/tao/libTAO.so.1.7.6)
==15653==    by 0x424243D: TAO_IIOP_Transport::send_message(TAO_OutputCDR&, TAO_Stub*, TAO_Message_Semantics, ACE_Time_Value*) (in /home/ACE_TAO_5.7.6/ACE_wrappers/TAO/tao/libTAO.so.1.7.6)
==15653==    by 0x42423D8: TAO_IIOP_Transport::send_request(TAO_Stub*, TAO_ORB_Core*, TAO_OutputCDR&, TAO_Message_Semantics, ACE_Time_Value*) (in /home/ACE_TAO_5.7.6/ACE_wrappers/TAO/tao/libTAO.so.1.7.6)
==15653==    by 0x42788C6: TAO::Remote_Invocation::send_message(TAO_OutputCDR&, TAO_Message_Semantics, ACE_Time_Value*) (in /home/ACE_TAO_5.7.6/ACE_wrappers/TAO/tao/libTAO.so.1.7.6)
==15653==    by 0x42810E3: TAO::Synch_Oneway_Invocation::remote_oneway(ACE_Time_Value*) (in /home/ACE_TAO_5.7.6/ACE_wrappers/TAO/tao/libTAO.so.1.7.6)
==15653==    by 0x424481E: TAO::Invocation_Adapter::invoke_oneway(TAO_Operation_Details&, TAO_Pseudo_Var_T<CORBA::Object>&, TAO::Profile_Transport_Resolver&, ACE_Time_Value*&) (in /home/ACE_TAO_5.7.6/ACE_wrappers/TAO/tao/libTAO.so.1.7.6)
==15653==    by 0x424461F: TAO::Invocation_Adapter::invoke_remote_i(TAO_Stub*, TAO_Operation_Details&, TAO_Pseudo_Var_T<CORBA::Object>&, ACE_Time_Value*&) (in /home/ACE_TAO_5.7.6/ACE_wrappers/TAO/tao/libTAO.so.1.7.6)
==15653==    by 0x424427E: TAO::Invocation_Adapter::invoke_i(TAO_Stub*, TAO_Operation_Details&) (in /home/ACE_TAO_5.7.6/ACE_wrappers/TAO/tao/libTAO.so.1.7.6)
==15653==    by 0x4244069: TAO::Invocation_Adapter::invoke(TAO::Exception_Data*, unsigned long) (in /home/ACE_TAO_5.7.6/ACE_wrappers/TAO/tao/libTAO.so.1.7.6)
==15653==    by 0x804EBC4: TestIF::TestMessage2(TestData const&) (testC.cpp:313)
==15653==    by 0x8052A7A: ClientWorker::svc() (Objref_VarOut_T.inl:25)
==15653==    by 0x41298AD: ACE_Task_Base::svc_run(void*) (in /home/ACE_TAO_5.7.6/ACE_wrappers/ace/libACE.so.5.7.6)
==15653==    by 0x4129C6D: ACE_Thread_Adapter::invoke_i() (in /home/ACE_TAO_5.7.6/ACE_wrappers/ace/libACE.so.5.7.6)
==15653==    by 0x4129BD3: ACE_Thread_Adapter::invoke() (in /home/ACE_TAO_5.7.6/ACE_wrappers/ace/libACE.so.5.7.6)
==15653==    by 0x40CADA6: ace_thread_adapter (in /home/ACE_TAO_5.7.6/ACE_wrappers/ace/libACE.so.5.7.6)
==15653==    by 0x9FF98B: start_thread (in /lib/tls/libpthread-0.61.so)
==15653==    by 0x79F169: clone (in /lib/tls/libc-2.3.3.so)
==15653== 
==15653== LEAK SUMMARY:
==15653==    definitely lost: 3,920 bytes in 98 blocks.
==15653==      possibly lost: 13,960 bytes in 23 blocks.
==15653==    still reachable: 53,578,605 bytes in 1,062 blocks.

Although valgrind reports the memory as "reachable", the memory is never freed in the Client application.  I also ran more tests while changing the oneway parameter message size and found that the memory leak only occurs for oneway calls with an input parameter size larger than 128k.
Comment 1 Chris Galli 2011-02-25 09:19:56 CST
Created attachment 1355 [details]
Possible fix for the memory leak.

I dug into this a little and it appears that the issue is in the Synch_Queued_Message class. At some point one of these is created on the stack, and during its lifetime a call to "copy_if_necessary" is made, which causes it to clone the underlying message block. Later when it is destroyed, that cloned block is never released.

My solution was to ensure the cloned block gets released in the destructor, because when on of these objects is created on the stack, the destroy method is never called, where the cloned block would normally get released.

I testing using the attached example and valgrind to verify it was no longer leaking.
Comment 2 Johnny Willemsen 2011-02-25 09:23:52 CST
For integration of the example, looks easier to take the tao hello world and update the idl and servant, removes the dependency on the naming service
Comment 3 Johnny Willemsen 2011-02-25 09:32:22 CST
added blocks
Comment 4 Vladimir Zykov 2011-02-25 09:34:06 CST
Big_Oneways reproduces this problem. Also it has few other leaks local to the test but I have a fix for those. So, the provided patch fixes the leak in TAO and quick testing didn't show any other problem.
Comment 5 Vladimir Zykov 2011-03-02 10:17:21 CST
In revision 93465.

Wed Mar  2 16:02:01 UTC 2011  Vladimir Zykov  <vladimir.zykov@prismtech.com>

        * tao/Synch_Queued_Message.cpp:
          Fixed leak of contents in synch queued message. Thanks to
          Chris Galli <christian dot galli at gmail dot com> for providing
          this fix. It fixes bug#3825.

        * tests/Big_Oneways/server.cpp:
        * tests/Big_Oneways/Session.cpp:
        * tests/Big_Oneways/Coordinator.cpp:
          Fixed leaks local to this test.