Bug #3502
Updated by Junxiao Shi over 7 years ago
A potential This was detected by clang's undefined behavior sanitizer (UBSan) during the execution of `TestRibManager/RibStatusRequest` test case. ``` Entering test case "RibStatusRequest" 1415684132.000000 INFO: [RibManager] Listening on: /localhost/nfd/rib 1415684132.000000 INFO: [RibManager] Start monitoring face create/destroy events /usr/include/boost/chrono/duration.hpp:558:32: runtime error: signed integer overflow exists overflow: -9223372036854775808 - 1000000 cannot be represented in `RibManager::listEntries` type 'long' #0 0x976c3a in boost::common_type<boost::chrono::duration<long, boost::ratio<1l, 1000000000l> >, boost::chrono::duration<long, boost::ratio<1l, 1000000000l> > >::type boost::chrono::operator-<long, boost::ratio<1l, 1000000000l>, long, boost::ratio<1l, 1000000000l> >(boost::chrono::duration<long, boost::ratio<1l, 1000000000l> > const&, boost::chrono::duration<long, boost::ratio<1l, 1000000000l> > const&) /usr/include/boost/chrono/duration.hpp:558:32 #1 0x97635a in boost::common_type<boost::chrono::duration<long, boost::ratio<1l, 1000000000l> >, boost::chrono::duration<long, boost::ratio<1l, 1000000000l> > >::type boost::chrono::operator-<ndn::time::steady_clock, boost::chrono::duration<long, boost::ratio<1l, 1000000000l> >, boost::chrono::duration<long, boost::ratio<1l, 1000000000l> > >(boost::chrono::time_point<ndn::time::steady_clock, boost::chrono::duration<long, boost::ratio<1l, 1000000000l> > > const&, boost::chrono::time_point<ndn::time::steady_clock, boost::chrono::duration<long, boost::ratio<1l, 1000000000l> > > const&) /usr/include/boost/chrono/time_point.hpp:286:39 #2 0x973ad6 in nfd::rib::RibStatusPublisher::generate(ndn::encoding::EncodingImpl<true>&) /home/davide/NFD/build/../rib/rib-status-publisher.cpp:75:29 #3 0x71440f in nfd::SegmentPublisher<ndn::Face>::publish() /home/davide/NFD/core/segment-publisher.hpp:76:5 #4 0x8b1b23 in nfd::rib::RibManager::listEntries(ndn::Interest const&) /home/davide/NFD/build/../rib/rib-manager.cpp:647:3 #5 0x8e3e1f in void std::_Mem_fn<void (nfd::rib::RibManager::*)(ndn::Interest const&)>::operator()<ndn::Interest const&, void>(nfd::rib::RibManager*, ndn::Interest const&) const /usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/include/g++-v4/functional:569:11 #6 0x8e34f0 in std::_Function_handler<void (nfd::rib::RibManager*, ndn::Interest const&), void (nfd::rib::RibManager::*)(ndn::Interest const&)>::_M_invoke(std::_Any_data const&, nfd::rib::RibManager*, ndn::Interest const&) /usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/include/g++-v4/functional:2126:2 #7 0x8d577b in std::function<void (nfd::rib::RibManager*, ndn::Interest const&)>::operator()(nfd::rib::RibManager*, ndn::Interest const&) const /usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/include/g++-v4/functional:2439:14 #8 0x8b8f85 in nfd::rib::RibManager::onLocalhostRequest(ndn::Interest const&) /home/davide/NFD/build/../rib/rib-manager.cpp:211:5 #9 0x8e3e1f in void std::_Mem_fn<void (nfd::rib::RibManager::*)(ndn::Interest const&)>::operator()<ndn::Interest const&, void>(nfd::rib::RibManager*, ndn::Interest const&) const /usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/include/g++-v4/functional:569:11 #10 0x91179e in void std::_Bind<std::_Mem_fn<void (nfd::rib::RibManager::*)(ndn::Interest const&)> (nfd::rib::RibManager*, std::_Placeholder<2>)>::__call<void, ndn::InterestFilter const&, ndn::Interest const&, 0ul, 1ul>(std::tuple<ndn::InterestFilter const&, ndn::Interest const&>&&, std::_Index_tuple<0ul, 1ul>) /usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/include/g++-v4/functional:1263:11 #11 0x911181 in void std::_Bind<std::_Mem_fn<void (nfd::rib::RibManager::*)(ndn::Interest const&)> (nfd::rib::RibManager*, std::_Placeholder<2>)>::operator()<ndn::InterestFilter const&, ndn::Interest const&, void>(ndn::InterestFilter const&, ndn::Interest const&) /usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/include/g++-v4/functional:1321:11 #12 0x90f91a in std::_Function_handler<void (ndn::InterestFilter const&, ndn::Interest const&), std::_Bind<std::_Mem_fn<void (nfd::rib::RibManager::*)(ndn::Interest const&)> (nfd::rib::RibManager*, std::_Placeholder<2>)> >::_M_invoke(std::_Any_data const&, ndn::InterestFilter const&, ndn::Interest const&) /usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/include/g++-v4/functional:2039:2 #13 0x3687eb94d7d in ndn::Face::onReceiveElement(ndn::Block const&) (/usr/lib64/libndn-cxx.so.0.4.0+0x182d7d) #14 0x3687ecf709d in void ndn::util::DummyClientFace::receive<ndn::Interest>(ndn::Interest const&) (/usr/lib64/libndn-cxx.so.0.4.0+0x2e509d) #15 0x6890aa in nfd::rib::tests::TestRibManager::RibStatusRequest::test_method() /home/davide/NFD/build/../tests/rib/rib-manager.t.cpp:322:3 #16 0x6884ea in nfd::rib::tests::TestRibManager::RibStatusRequest_invoker() /home/davide/NFD/build/../tests/rib/rib-manager.t.cpp:310:1 #17 0x5729a2 in boost::unit_test::ut_detail::unused boost::unit_test::ut_detail::invoker<boost::unit_test::ut_detail::unused>::invoke<void (*)()>(void (*&)()) /usr/include/boost/test/utils/callback.hpp:56:59 #18 0x5727f3 in boost::unit_test::ut_detail::callback0_impl_t<boost::unit_test::ut_detail::unused, void (*)()>::invoke() /usr/include/boost/test/utils/callback.hpp:89:33 #19 0x3687f066110 (/usr/lib64/libboost_unit_test_framework.so.1.58.0+0x6d110) #20 0x3687f044f45 in boost::execution_monitor::catch_signals(boost::unit_test::callback0<int> const&) (/usr/lib64/libboost_unit_test_framework.so.1.58.0+0x4bf45) #21 0x3687f045772 in boost::execution_monitor::execute(boost::unit_test::callback0<int> const&) (/usr/lib64/libboost_unit_test_framework.so.1.58.0+0x4c772) #22 0x3687f066224 in boost::unit_test::unit_test_monitor_t::execute_and_translate(boost::unit_test::test_case const&) (/usr/lib64/libboost_unit_test_framework.so.1.58.0+0x6d224) #23 0x3687f04c76e in boost::unit_test::framework_impl::visit(boost::unit_test::test_case const&) (/usr/lib64/libboost_unit_test_framework.so.1.58.0+0x5376e) #24 0x3687f081a42 in boost::unit_test::traverse_test_tree(boost::unit_test::test_suite const&, boost::unit_test::test_tree_visitor&) (/usr/lib64/libboost_unit_test_framework.so.1.58.0+0x88a42) #25 0x3687f081a42 in boost::unit_test::traverse_test_tree(boost::unit_test::test_suite const&, boost::unit_test::test_tree_visitor&) (/usr/lib64/libboost_unit_test_framework.so.1.58.0+0x88a42) #26 0x3687f047c39 in boost::unit_test::framework::run(unsigned long, bool) (/usr/lib64/libboost_unit_test_framework.so.1.58.0+0x4ec39) #27 0x3687f063e36 in boost::unit_test::unit_test_main(bool (*)(), int, char**) (/usr/lib64/libboost_unit_test_framework.so.1.58.0+0x6ae36) #28 0xa6cbea in main /home/davide/NFD/build/../tests/main.cpp:104:10 #29 0x3687c5bf61f in __libc_start_main (/lib64/libc.so.6+0x2061f) #30 0x45c608 in _start (/home/davide/NFD/build/unit-tests-rib+0x45c608) Leaving test case "RibStatusRequest"; testing time: 12657mks ``` **Explanation** `Route::expires` is initialized to `TimePoint::min()` in the constructor and `Route`'s stream output operator. left untouched by the test case. The following line triggers an UBSan error: (negative) overflow happens in `RibStatusPublisher::generate()`: ``` ```cpp boost::lexical_cast<std::string>(rib::Route{}); time::duration_cast<time::milliseconds>(route.expires - time::steady_clock::now()) ``` I believe `generate()` should not assume that `route.expires` is always greater than or equal to `now()`, unless some other internal logic is able to guarantee that, in which case we should still add a `BOOST_ASSERT` to the function and fix the test case.