Bug 1377

Summary: valgrind error in test suite ipv6-dual-stack
Product: ns-3 Reporter: Tom Henderson <tomh>
Component: ipv6Assignee: Tommaso Pecorella <tommaso.pecorella>
Status: RESOLVED FIXED    
Severity: normal CC: ns-bugs
Priority: P5    
Version: pre-release   
Hardware: All   
OS: All   
Attachments: Callback nullified on socket.cc
Nullify some (maybe) relevant callbacks.
The memory leak and some quite nasty silent ones.

Description Tom Henderson 2012-02-25 11:27:59 UTC
Our FC 15 (64-bit) buildslave is showing this valgrind error:

./test.py -s ipv6-dual-stack -t out.txt -g               

VALGR: TestSuite ipv6-dual-stack
0 of 1 tests passed (0 passed, 0 skipped, 0 failed, 0 crashed, 1 valgrind errors)

More details:

[buildslave@buildslave utils]$ valgrind --leak-check=full --show-reachable=yes ./ns3-dev-test-runner-debug --suite=ipv6-dual-stack
==17026== Memcheck, a memory error detector
==17026== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==17026== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==17026== Command: ./ns3-dev-test-runner-debug --suite=ipv6-dual-stack
==17026== 
PASS ipv6-dual-stack 2.050ms
==17026== 
==17026== HEAP SUMMARY:
==17026==     in use at exit: 328 bytes in 8 blocks
==17026==   total heap usage: 10,772 allocs, 10,764 frees, 842,555 bytes allocated
==17026== 
==17026== 16 bytes in 1 blocks are still reachable in loss record 1 of 8
==17026==    at 0x4A0649D: malloc (vg_replace_malloc.c:236)
==17026==    by 0xD981818: ns3::Object::Object() (object.cc:88)
==17026==    by 0xAA99B55: ns3::SimulatorImpl::SimulatorImpl() (simulator-impl.h:35)
==17026==    by 0xD96F412: ns3::DefaultSimulatorImpl::DefaultSimulatorImpl() (default-simulator-impl.cc:49)
==17026==    by 0xD970AB8: ns3::TypeId ns3::TypeId::AddConstructor<ns3::DefaultSimulatorImpl>()::Maker::Create() (type-id.h:392)
==17026==    by 0x4F01D61: ns3::FunctorCallbackImpl<ns3::ObjectBase* (*)(), ns3::ObjectBase*, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty>::operator()() (callback.h:166)
==17026==    by 0xCE9AFFE: ns3::Callback<ns3::ObjectBase*, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty>::operator()() const (callback.h:407)
==17026==    by 0xD99F083: ns3::ObjectFactory::Create() const (object-factory.cc:85)
==17026==    by 0xD96E241: ns3::Ptr<ns3::SimulatorImpl> ns3::ObjectFactory::Create<ns3::SimulatorImpl>() const (object-factory.h:149)
==17026==    by 0xD96AE21: ns3::GetImpl() (simulator.cc:93)
==17026==    by 0xD96C4BA: ns3::Simulator::DoScheduleDestroy(ns3::EventImpl*) (simulator.cc:240)
==17026==    by 0xD96CC62: ns3::Simulator::ScheduleDestroy(void (*)()) (simulator.cc:269)
==17026== 
==17026== 16 bytes in 1 blocks are still reachable in loss record 2 of 8
==17026==    at 0x4A0649D: malloc (vg_replace_malloc.c:236)
==17026==    by 0xD981818: ns3::Object::Object() (object.cc:88)
==17026==    by 0xD960797: ns3::Scheduler::Scheduler() (scheduler.h:53)
==17026==    by 0xD9618CE: ns3::MapScheduler::MapScheduler() (map-scheduler.cc:44)
==17026==    by 0xD9628E5: ns3::TypeId ns3::TypeId::AddConstructor<ns3::MapScheduler>()::Maker::Create() (type-id.h:392)
==17026==    by 0x4F01D61: ns3::FunctorCallbackImpl<ns3::ObjectBase* (*)(), ns3::ObjectBase*, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty>::operator()() (callback.h:166)
==17026==    by 0xCE9AFFE: ns3::Callback<ns3::ObjectBase*, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty>::operator()() const (callback.h:407)
==17026==    by 0xD99F083: ns3::ObjectFactory::Create() const (object-factory.cc:85)
==17026==    by 0xAA9A231: ns3::Ptr<ns3::Scheduler> ns3::ObjectFactory::Create<ns3::Scheduler>() const (object-factory.h:149)
==17026==    by 0xD96F879: ns3::DefaultSimulatorImpl::SetScheduler(ns3::ObjectFactory) (default-simulator-impl.cc:97)
==17026==    by 0xD96AF09: ns3::GetImpl() (simulator.cc:100)
==17026==    by 0xD96C4BA: ns3::Simulator::DoScheduleDestroy(ns3::EventImpl*) (simulator.cc:240)
==17026== 
==17026== 24 bytes in 1 blocks are still reachable in loss record 3 of 8
==17026==    at 0x4A05F97: operator new(unsigned long) (vg_replace_malloc.c:261)
==17026==    by 0xD97332E: ns3::MakeEvent(void (*)()) (make-event.cc:27)
==17026==    by 0xD96CC4D: ns3::Simulator::ScheduleDestroy(void (*)()) (simulator.cc:269)
==17026==    by 0xD1F71F1: ns3::NodeListPriv::DoGet() (node-list.cc:87)
==17026==    by 0xD1F70E8: ns3::NodeListPriv::Get() (node-list.cc:77)
==17026==    by 0xD1F7B6F: ns3::NodeList::Add(ns3::Ptr<ns3::Node>) (node-list.cc:168)
==17026==    by 0xD1ED407: ns3::Node::Construct() (node.cc:86)
==17026==    by 0xD1ED25E: ns3::Node::Node() (node.cc:73)
==17026==    by 0x5C24708: ns3::Ptr<ns3::Node> ns3::CreateObject<ns3::Node>() (object.h:393)
==17026==    by 0x9AED603: ns3::CreateDualStackNode() (ipv6-dual-stack-test-suite.cc:91)
==17026==    by 0x9AEE1F3: ns3::DualStackTestCase::SetUpSim() (ipv6-dual-stack-test-suite.cc:165)
==17026==    by 0x9AEEF01: ns3::DualStackTestCase::DoRun() (ipv6-dual-stack-test-suite.cc:234)
==17026== 
==17026== 24 bytes in 1 blocks are still reachable in loss record 4 of 8
==17026==    at 0x4A05F97: operator new(unsigned long) (vg_replace_malloc.c:261)
==17026==    by 0xD97332E: ns3::MakeEvent(void (*)()) (make-event.cc:27)
==17026==    by 0xD96CC4D: ns3::Simulator::ScheduleDestroy(void (*)()) (simulator.cc:269)
==17026==    by 0xD1E4FD1: ns3::ChannelListPriv::DoGet() (channel-list.cc:87)
==17026==    by 0xD1E4EC8: ns3::ChannelListPriv::Get() (channel-list.cc:76)
==17026==    by 0xD1E58CF: ns3::ChannelList::Add(ns3::Ptr<ns3::Channel>) (channel-list.cc:161)
==17026==    by 0xD1E43B6: ns3::Channel::Channel() (channel.cc:49)
==17026==    by 0xD252B0E: ns3::SimpleChannel::SimpleChannel() (simple-channel.cc:43)
==17026==    by 0x5C2AE5B: ns3::Ptr<ns3::SimpleChannel> ns3::CreateObject<ns3::SimpleChannel>() (object.h:393)
==17026==    by 0x9AEE411: ns3::DualStackTestCase::SetUpSim() (ipv6-dual-stack-test-suite.cc:173)
==17026==    by 0x9AEEF01: ns3::DualStackTestCase::DoRun() (ipv6-dual-stack-test-suite.cc:234)
==17026==    by 0xD983789: ns3::TestCase::Run(ns3::TestRunnerImpl*) (test.cc:207)
==17026== 
==17026== 40 bytes in 1 blocks are still reachable in loss record 5 of 8
==17026==    at 0x4A05F97: operator new(unsigned long) (vg_replace_malloc.c:261)
==17026==    by 0xAA9B421: __gnu_cxx::new_allocator<std::_List_node<ns3::EventId> >::allocate(unsigned long, void const*) (new_allocator.h:92)
==17026==    by 0xAA9B277: std::_List_base<ns3::EventId, std::allocator<ns3::EventId> >::_M_get_node() (stl_list.h:327)
==17026==    by 0xAA9B080: std::list<ns3::EventId, std::allocator<ns3::EventId> >::_M_create_node(ns3::EventId const&) (stl_list.h:473)
==17026==    by 0xAA9ABAA: std::list<ns3::EventId, std::allocator<ns3::EventId> >::_M_insert(std::_List_iterator<ns3::EventId>, ns3::EventId const&) (stl_list.h:1515)
==17026==    by 0xAA9A553: std::list<ns3::EventId, std::allocator<ns3::EventId> >::push_back(ns3::EventId const&) (stl_list.h:988)
==17026==    by 0xD9705F5: ns3::DefaultSimulatorImpl::ScheduleDestroy(ns3::EventImpl*) (default-simulator-impl.cc:239)
==17026==    by 0xD96C4D5: ns3::Simulator::DoScheduleDestroy(ns3::EventImpl*) (simulator.cc:240)
==17026==    by 0xD96CC62: ns3::Simulator::ScheduleDestroy(void (*)()) (simulator.cc:269)
==17026==    by 0xD1F71F1: ns3::NodeListPriv::DoGet() (node-list.cc:87)
==17026==    by 0xD1F70E8: ns3::NodeListPriv::Get() (node-list.cc:77)
==17026==    by 0xD1F7B6F: ns3::NodeList::Add(ns3::Ptr<ns3::Node>) (node-list.cc:168)
==17026== 
==17026== 40 bytes in 1 blocks are still reachable in loss record 6 of 8
==17026==    at 0x4A05F97: operator new(unsigned long) (vg_replace_malloc.c:261)
==17026==    by 0xAA9B421: __gnu_cxx::new_allocator<std::_List_node<ns3::EventId> >::allocate(unsigned long, void const*) (new_allocator.h:92)
==17026==    by 0xAA9B277: std::_List_base<ns3::EventId, std::allocator<ns3::EventId> >::_M_get_node() (stl_list.h:327)
==17026==    by 0xAA9B080: std::list<ns3::EventId, std::allocator<ns3::EventId> >::_M_create_node(ns3::EventId const&) (stl_list.h:473)
==17026==    by 0xAA9ABAA: std::list<ns3::EventId, std::allocator<ns3::EventId> >::_M_insert(std::_List_iterator<ns3::EventId>, ns3::EventId const&) (stl_list.h:1515)
==17026==    by 0xAA9A553: std::list<ns3::EventId, std::allocator<ns3::EventId> >::push_back(ns3::EventId const&) (stl_list.h:988)
==17026==    by 0xD9705F5: ns3::DefaultSimulatorImpl::ScheduleDestroy(ns3::EventImpl*) (default-simulator-impl.cc:239)
==17026==    by 0xD96C4D5: ns3::Simulator::DoScheduleDestroy(ns3::EventImpl*) (simulator.cc:240)
==17026==    by 0xD96CC62: ns3::Simulator::ScheduleDestroy(void (*)()) (simulator.cc:269)
==17026==    by 0xD1E4FD1: ns3::ChannelListPriv::DoGet() (channel-list.cc:87)
==17026==    by 0xD1E4EC8: ns3::ChannelListPriv::Get() (channel-list.cc:76)
==17026==    by 0xD1E58CF: ns3::ChannelList::Add(ns3::Ptr<ns3::Channel>) (channel-list.cc:161)
==17026== 
==17026== 80 bytes in 1 blocks are still reachable in loss record 7 of 8
==17026==    at 0x4A05F97: operator new(unsigned long) (vg_replace_malloc.c:261)
==17026==    by 0xD9628DA: ns3::TypeId ns3::TypeId::AddConstructor<ns3::MapScheduler>()::Maker::Create() (type-id.h:392)
==17026==    by 0x4F01D61: ns3::FunctorCallbackImpl<ns3::ObjectBase* (*)(), ns3::ObjectBase*, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty>::operator()() (callback.h:166)
==17026==    by 0xCE9AFFE: ns3::Callback<ns3::ObjectBase*, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty>::operator()() const (callback.h:407)
==17026==    by 0xD99F083: ns3::ObjectFactory::Create() const (object-factory.cc:85)
==17026==    by 0xAA9A231: ns3::Ptr<ns3::Scheduler> ns3::ObjectFactory::Create<ns3::Scheduler>() const (object-factory.h:149)
==17026==    by 0xD96F879: ns3::DefaultSimulatorImpl::SetScheduler(ns3::ObjectFactory) (default-simulator-impl.cc:97)
==17026==    by 0xD96AF09: ns3::GetImpl() (simulator.cc:100)
==17026==    by 0xD96C4BA: ns3::Simulator::DoScheduleDestroy(ns3::EventImpl*) (simulator.cc:240)
==17026==    by 0xD96CC62: ns3::Simulator::ScheduleDestroy(void (*)()) (simulator.cc:269)
==17026==    by 0xD1F71F1: ns3::NodeListPriv::DoGet() (node-list.cc:87)
==17026==    by 0xD1F70E8: ns3::NodeListPriv::Get() (node-list.cc:77)
==17026== 
==17026== 88 bytes in 1 blocks are still reachable in loss record 8 of 8
==17026==    at 0x4A05F97: operator new(unsigned long) (vg_replace_malloc.c:261)
==17026==    by 0xD970AAD: ns3::TypeId ns3::TypeId::AddConstructor<ns3::DefaultSimulatorImpl>()::Maker::Create() (type-id.h:392)
==17026==    by 0x4F01D61: ns3::FunctorCallbackImpl<ns3::ObjectBase* (*)(), ns3::ObjectBase*, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty>::operator()() (callback.h:166)
==17026==    by 0xCE9AFFE: ns3::Callback<ns3::ObjectBase*, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty>::operator()() const (callback.h:407)
==17026==    by 0xD99F083: ns3::ObjectFactory::Create() const (object-factory.cc:85)
==17026==    by 0xD96E241: ns3::Ptr<ns3::SimulatorImpl> ns3::ObjectFactory::Create<ns3::SimulatorImpl>() const (object-factory.h:149)
==17026==    by 0xD96AE21: ns3::GetImpl() (simulator.cc:93)
==17026==    by 0xD96C4BA: ns3::Simulator::DoScheduleDestroy(ns3::EventImpl*) (simulator.cc:240)
==17026==    by 0xD96CC62: ns3::Simulator::ScheduleDestroy(void (*)()) (simulator.cc:269)
==17026==    by 0xD1F71F1: ns3::NodeListPriv::DoGet() (node-list.cc:87)
==17026==    by 0xD1F70E8: ns3::NodeListPriv::Get() (node-list.cc:77)
==17026==    by 0xD1F7B6F: ns3::NodeList::Add(ns3::Ptr<ns3::Node>) (node-list.cc:168)
==17026== 
==17026== LEAK SUMMARY:
==17026==    definitely lost: 0 bytes in 0 blocks
==17026==    indirectly lost: 0 bytes in 0 blocks
==17026==      possibly lost: 0 bytes in 0 blocks
==17026==    still reachable: 328 bytes in 8 blocks
==17026==         suppressed: 0 bytes in 0 blocks
==17026== 
==17026== For counts of detected and suppressed errors, rerun with: -v
==17026== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)
Comment 1 Tommaso Pecorella 2012-02-25 13:41:23 UTC
Created attachment 1340 [details]
Callback nullified on socket.cc

Doesn't seems to be related to IPv6 specifically, but to a generic Callback not nullified properly (again).

Can you try this patch ?

Thanks,

T.
Comment 2 Tommaso Pecorella 2012-02-25 14:19:50 UTC
Created attachment 1341 [details]
Nullify some (maybe) relevant callbacks.

Nullified more Callbacks, also on IPv4
Comment 3 Tom Henderson 2012-02-25 20:54:10 UTC
(In reply to comment #2)
> Created attachment 1341 [details]
> Nullify some (maybe) relevant callbacks.
> 
> Nullified more Callbacks, also on IPv4

Neither this nor the more general idea of putting Nullify in the Callback destructor fixed the issue.
Comment 4 Tommaso Pecorella 2012-02-25 21:34:35 UTC
(In reply to comment #3)
> (In reply to comment #2)
> > Created attachment 1341 [details]
> > Nullify some (maybe) relevant callbacks.
> > 
> > Nullified more Callbacks, also on IPv4
> 
> Neither this nor the more general idea of putting Nullify in the Callback
> destructor fixed the issue.

I think I have an idea about what's the problem. It would be interesting to test it on Udp sockets, if they could do a connect ... :)

Anyway, it's about the fact that a TCP socket shouldn't "bind" to both IPv4 *and* IPv6, but if they do bind on IPv6 they can still receive "pseudo-IPv4" connections. That's disturbing. I'll try to scavenge more the thing.

Dual stack nodes should be forbidden (in general, not only in ns-3).

T.
Comment 5 Tommaso Pecorella 2012-02-26 13:44:19 UTC
Created attachment 1342 [details]
The memory leak and some quite nasty silent ones.

Vittu !

DoTeardown should ALWAYS call Simulator::Destroy();

So dramatically stupid that I didn't check it.

On the other hand, another case of serendipity. I found number of hidden bugs that were just lurking in the dark. Check the patch please.
Comment 6 Tom Henderson 2012-02-27 01:00:40 UTC
(In reply to comment #5)
> Created attachment 1342 [details]
> The memory leak and some quite nasty silent ones.
> 
> Vittu !
> 
> DoTeardown should ALWAYS call Simulator::Destroy();
> 
> So dramatically stupid that I didn't check it.
> 
> On the other hand, another case of serendipity. I found number of hidden bugs
> that were just lurking in the dark. Check the patch please.


looks ok to me
Comment 7 Tommaso Pecorella 2012-02-27 13:03:14 UTC
Fixed: changeset 7747 - 53a26ce38807