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