Skip to content

core: prevent static initialization issue with Time::Resolution on Cppyy 3

After updating to Cppyy, trying to run ns-3 scripts will fail. Here is an example of such a failure.

 ./ns3 run first.py
[0/2] Re-checking globbed directories...
[runStaticInitializersOnce]: Failed to materialize symbols: { (main, { _GLOBAL__sub_I_cling_module_138, __cxx_global_var_initcling_module_138_, __orc_init_func.cling-module-138, $.cling-module-138.__inits.0, _ZN3ns3L16g_TimeStaticInitE }) }
[runStaticInitializersOnce]: Failed to materialize symbols: { (main, { __orc_init_func.cling-module-138 }) }
[runStaticInitializersOnce]: Failed to materialize symbols: { (main, { _ZN3ns34TimeD1Ev, _ZZN3ns34Time14PeekResolutionEvE10resolution, _ZN3ns3L27UE_MEASUREMENT_REPORT_DELAYE, $.cling-module-158.__inits.0, _GLOBAL__sub_I_cling_module_158, __cxx_global_var_initcling_module_158_, _ZGVZN3ns34Time14PeekResolutionEvE10resolution, __orc_init_func.cling-module-158 }) }
[runStaticInitializersOnce]: Failed to materialize symbols: { (main, { __orc_init_func.cling-module-158 }) }
cling JIT session error: Failed to materialize symbols: { (main, { _ZGVZN3ns34Time14PeekResolutionEvE10resolution }) }
cling JIT session error: Failed to materialize symbols: { (main, { _ZN3ns34Time4FromERKNS_10int64x64_tENS0_4UnitE }) }
Traceback (most recent call last):
  File "/ns-3-dev/examples/tutorial/first.py", line 49, in <module>
    serverApps.Start(ns.core.Seconds(1.0))
TypeError: none of the 2 overloaded methods succeeded. Full details:
  ns3::Time ns3::Seconds(ns3::int64x64_t value) =>
    TypeError: could not convert argument 1
  ns3::Time ns3::Seconds(double value) =>
    ValueError: nullptr result where temporary expected
Command 'python3 /ns-3-dev/examples/tutorial/first.py' returned non-zero exit status 1.

The source of the issue is in the serverApps.Start(ns.core.Seconds(1.0)) statement.

While testing, I tried the following:

# does work
int64x64 = ns.core.int64x64_t(1.0)
timeval_i64x64 = ns.core.Time(int64x64)
timeval_i = ns.core.Time(1)
timeval = ns.core.Time(1.0)
# doesn't work
secval = ns.core.Seconds(1.0)

When it reaches the last case, it throws an error:

  File "/ns-3-dev/examples/tutorial/first.py", line 54, in <module>
    secval = ns.core.Seconds(1.0)
TypeError: none of the 2 overloaded methods succeeded. Full details:
  ns3::Time ns3::Seconds(ns3::int64x64_t value) =>
    TypeError: could not convert argument 1
  ns3::Time ns3::Seconds(double value) =>
    ValueError: nullptr result where temporary expected

Process finished with exit code 1

Were we can se the overload that accepts a double reports a weird nullptr result where temporary expected. By applying the patch that makes Time::Resolution a static attribute of Time, the example works as expected.

At time +2s client sent 1024 bytes to 10.1.1.2 port 9
At time +2.00369s server received 1024 bytes from 10.1.1.1 port 49153
At time +2.00369s server sent 1024 bytes to 10.1.1.1 port 49153
At time +2.00737s client received 1024 bytes from 10.1.1.2 port 9

That nullptr comes from

inline Time
Seconds(double value)
{
    return Time::FromDouble(value, Time::S);
    //inline static Time FromDouble(double value, Unit unit)
    //{
    //  return From(int64x64_t(value), unit);
    //  //inline static Time From(const int64x64_t& value, Unit unit)
    //  //{
    //  //  struct Information* info = PeekInformation(unit); < source of the segmentation violation
    //  //  ...
    //  //}
    //}
}

Still checking if this really is our problem or cppyy.

Edited by Gabriel Ferreira

Merge request reports