Bugzilla – Bug 877
python bindings broken with multiple inheritance ?
Last modified: 2010-04-16 08:00:45 EDT
I tried running examples/mixed-wireless.py and I get this: Enabling OLSR routing on all backbone nodes Configuring local area network for backbone node 0 Configuring local area network for backbone node 1 Configuring local area network for backbone node 2 Configuring local area network for backbone node 3 Configuring local area network for backbone node 4 Configuring local area network for backbone node 5 Configuring local area network for backbone node 6 Configuring local area network for backbone node 7 Configuring local area network for backbone node 8 Configuring local area network for backbone node 9 Configuring wireless network for backbone node 0 Configuring wireless network for backbone node 1 Configuring wireless network for backbone node 2 Configuring wireless network for backbone node 3 Configuring wireless network for backbone node 4 Configuring wireless network for backbone node 5 Configuring wireless network for backbone node 6 Configuring wireless network for backbone node 7 Configuring wireless network for backbone node 8 Configuring wireless network for backbone node 9 Create Applications. Configure Tracing. (tracing not done for Python) assert failed. file=../src/core/type-id.cc, line=138, cond="uid <= m_information.size () && uid != 0" backtrace: #1 0x00007fffef61b566 in (anonymous namespace)::IidManager::GetConstructor (this=0x7ffff04b9110, uid= 0) at ../src/core/type-id.cc:211 #2 0x00007fffef61db69 in ns3::TypeId::GetConstructor (this=0x7fffffffd638) at ../src/core/type-id.cc:596 #3 0x00007fffef65ed1d in ns3::ObjectFactory::Create (this=0x7fffffffd638) at ../src/core/object-factory.cc:68 #4 0x00007fffefcfb63b in ns3::ObjectFactory::Create<ns3::YansWifiPhy> (this=0x7fffffffd638) at debug/ns3/object-factory.h:110 #5 0x00007fffefcf92f6 in ns3::YansWifiPhyHelper::Create (this=0x7fffffffd620, node=..., device=Cannot access memory at address 0x0 ) at ../src/helper/yans-wifi-helper.cc:233 #6 0x00007fffefd2a723 in ns3::PcapHelperForDevice::EnablePcap (this=0x78bac0, prefix= "mixed-wireless", nd=..., promiscuous=false, explicitFilename=false) at ../src/helper/trace-helper.cc:417 #7 0x00007fffefd2a964 in ns3::PcapHelperForDevice::EnablePcap (this=0x78bac0, prefix= "mixed-wireless", d=..., promiscuous=false) at ../src/helper/trace-helper.cc:433 #8 0x00007ffff0890e8d in _wrap_PyNs3PcapHelperForDevice_EnablePcap__2 (self=0x9687a0, args=0x968758, kwargs=0x0, return_exception=0x7fffffffd810) at debug/bindings/python/ns3_module_helper.cc:11952 #9 0x00007ffff089152e in _wrap_PyNs3PcapHelperForDevice_EnablePcap (self=0x9687a0, args=0x968758, kwargs=0x0) at debug/bindings/python/ns3_module_helper.cc:12027 #10 0x0000003136edcaba in call_function (f=<value optimized out>, throwflag=<value optimized out>) at Python/ceval.c:3706 Since this backtrace is impossible (see frames 5 and 6), this looks like some nasty multiple inheritance typecasting because of: class YansWifiPhyHelper : public WifiPhyHelper, public PcapHelperForDevice, public AsciiTraceHelperForDevice
I don't see anything wrong in the Python bindings. One thing the Python bindings do is this: ns3::YansWifiPhyHelper retval = ns3::YansWifiPhyHelper::Default(); [...] py_YansWifiPhyHelper->obj = new ns3::YansWifiPhyHelper(retval); This effectively requires the use a copy-constructor. Why? Because a stack-allocated return value is useless for the Python bindings, we need heap object instead. If there is something not being done right in the copy constructor, and I suspect so from the gdb session I had, then things might break. If so, the problem is in the wrapper for ns3::YansWifiPhyHelper::Default(), not in the method call on the instance.
There is something weird going on with the 'this' pointer when moving across virtual method calls from PcapHelperForDevice -> YansWifiPhyHelper (EnablePcapInternal). (gdb) f #6 0x00007ffff54c6043 in ns3::PcapHelperForDevice::EnablePcap (this=0xa13f50, prefix=..., nd=..., promiscuous=false, explicitFilename=false) at ../src/helper/trace-helper.cc:417 417 EnablePcapInternal (prefix, nd, promiscuous, explicitFilename); (gdb) down #5 0x00007ffff548f26e in ns3::YansWifiPhyHelper::Create (this=0x7fffffffd270, node=..., device=Cannot access memory at address 0x0 ) at ../src/helper/yans-wifi-helper.cc:233 233 Ptr<YansWifiPhy> phy = m_phy.Create<YansWifiPhy> (); (gdb) down #4 0x00007ffff5491681 in ns3::ObjectFactory::Create<ns3::YansWifiPhy> (this=0x7fffffffd288) at debug/ns3/object-factory.h:110 110 Ptr<Object> object = Create (); (gdb) Indeed, maybe there's something I am missing about MI and the bindings... I'll have to recheck this with more time...
(gdb) p py_YansWifiPhyHelper->obj $1 = (class ns3::YansWifiPhyHelper *) 0xa13f50 (gdb) p static_cast<ns3::PcapHelperForDevice*> ($1) $2 = (ns3::PcapHelperForDevice *) 0xa13f58 OK, so this is what I missed. Typecasting changes the 'this' pointer address when we have MI :-/
Created attachment 832 [details] remove multiple inheritance Since we are very close to freeze/release, I feel that the best way to deal with this bug is to simply remove multiple inheritance which we don't really need here anyway so, this patch: - merges together the ascii/pcap methods in TraceHelperForDevice - merges together the ascii/pcap ipv4/ipv6 methods in TraceHelperForIpvx
changeset: 6209:644530171fdd