BIND 10 #1727: IntervalTimerTest.invalidArgumentToIntervalTimer failure

BIND 10 Development do-not-reply at isc.org
Tue Mar 20 06:39:51 UTC 2012


#1727: IntervalTimerTest.invalidArgumentToIntervalTimer failure
-------------------------------------+-------------------------------------
                   Reporter:  jreed  |                 Owner:  jinmei
                       Type:         |                Status:  accepted
  defect                             |             Milestone:
                   Priority:         |  Sprint-20120320
  medium                             |            Resolution:
                  Component:         |             Sensitive:  0
  Unclassified                       |           Sub-Project:  Core
                   Keywords:         |  Estimated Difficulty:  7
            Defect Severity:  N/A    |           Total Hours:  0
Feature Depending on Ticket:         |
        Add Hours to Ticket:  0      |
                  Internal?:  0      |
-------------------------------------+-------------------------------------

Comment (by jinmei):

 trac1727 is ready for review.

 The change itself is simple: if Boost used for building BIND 10 tries
 to use threads by default, i.e., as a result of including
 boost/config.hpp, make that sure by explicitly defining
 BOOST_DISABLE_THREADS for the entire build environment.

 Why we need this for this problem is very complicated (described
 below).  But first, this is the proposed changelog:

 {{{
 405.?   [bug]           jinmei
         Make sure disabling Boost threads if the default configuration is
         to disable it for the system.  This fixes a crash and hang up
         problem on OpenBSD, where the use of Boost thread could be
         different in different program files depending on the order of
         including various header files, and could introduce inconsistent
         states between a library and a program.  Explicitly forcing the
         original default throughout the BIND 10 build environment will
         prevent this from happening.
         (Trac #1727, git TBD)
 }}}

 Then here is the reason:

 For the combination of BSD and g++, Boost apparently uses threads by
 default due to this setting in boost/config/gcc.hpp:
 {{{#!c++
 #if !defined(__MINGW32__) && !defined(linux) && !defined(__linux) &&
 !defined(__linux__)
 # define BOOST_HAS_THREADS
 #endif
 }}}

 But the OpenBSD package version of Boost skips this configuration by
 skipping importing system configurations:
 {{{#!c++
 #ifndef BOOST_NO_CONFIG
 #  define BOOST_NO_CONFIG
 #endif
 }}}
 (see boost/config/user.hpp)

 So, normally BOOST_HAS_THREADS shouldn't be defined for OpenBSD.  But
 this deviant OS introduces another hack to boost/config/suffix.hpp:
 {{{#!diff
  #if (defined(__MT__) || defined(_MT) || defined(_REENTRANT) \
 -    || defined(_PTHREADS) || defined(__APPLE__) ||
 defined(__DragonFly__)) \
 +    || defined(_PTHREADS) || defined(_POSIX_THREADS) \
 +    || defined(__APPLE__) || defined(__DragonFly__)) \
      && !defined(BOOST_HAS_THREADS)
  #  define BOOST_HAS_THREADS
  #endif
 }}}

 And `_POSIX_THREADS` is defined in /usr/includes/pthread.h.  So, if
 some preceding header before boost/config.hpp (which would be included
 as a result of any boost header files or asio.hpp) includes pthread.h
 (either directly or indirectly from other header files), that
 particular translation unit (.cc) has BOOST_HAS_THREADS defined.

 The latter case happens for, e.g.,
 asiolink/tests/udp_socket_unittest.cc (it seems to be a result of
 including <string>).  With or without the existence of
 BOOST_HAS_THREADS, one key class called task_io_service of ASIO will
 differ:
 {{{#!c++
 class task_io_service
   : public asio::detail::service_base<task_io_service>
 {
 public:
 ...
   // The count of unfinished work.
   boost::detail::atomic_count outstanding_work_;
 ...
 };
 }}}

 This atomic_count is long (8 bytes in many 64-bit systems) when
 BOOST_HAS_THREADS isn't defined, while it's a structure holding an int
 (normally 4 bytes) if BOOST_HAS_THREADS is defined.

 Within libasiolink, BOOST_HAS_THREADS doesn't seem to be defined, and
 task_io_service is instantiated in a function
 service_registry::create():
 {{{#!c++
 template <typename Service>
 asio::io_service::service* service_registry::create(
     asio::io_service& owner)
 {
   return new Service(owner);
 }
 }}}

 On the other hand, the test code itself includes asio.hpp and uses
 some of the definitions, and some functions use task_io_service class
 objects directly.  But the test code does not use all of the ASIO
 definitions (service_registry is one of them), so some of the
 functions still only exist within libasiolink and they are used.
 As a result, in a single program two different interpretations of
 the size of task_io_service (or of its internal definition in general)
 coexist, and caused various type of strange failures - sometimes
 crash, sometimes hang up.

 So, to solve this problem we need to make sure at least the status of
 BOOST_HAS_THREADS is consistent throughout BIND 10.  I considered
 several possibilities, and concluded this one was probably least ugly
 (in any case, the fix would be a hack).  With this approach we could
 at least be independent from specific OS, and we can also enable this
 when we really need to use boost threads.

-- 
Ticket URL: <http://bind10.isc.org/ticket/1727#comment:6>
BIND 10 Development <http://bind10.isc.org>
BIND 10 Development


More information about the bind10-tickets mailing list