Boost logo

Boost :

From: Felipe Magno de Almeida (felipe.m.almeida_at_[hidden])
Date: 2006-04-06 10:49:43


Hello,

I'm using an AMD64 X2 and sometimes the program fails with the
debugger showing me this call stack:

> basic.exe!`anonymous namespace'::get_slots(bool alloc=false) Line
108 + 0x5 C++
         basic.exe!boost::detail::tss::get() Line 164 + 0x7 C++
         basic.exe!boost::thread_specific_ptr<boost::weak_ptr<boost::spirit::impl::grammar_helper<boost::spirit::grammar<smtp_client::impl::grammars::greeting_response,boost::spirit::parser_context<boost::spirit::nil_t>
>,smtp_client::impl::grammars::greeting_response,boost::spirit::scanner<char
*,boost::spirit::scanner_policies<boost::spirit::iteration_policy,boost::spirit::match_policy,boost::spirit::action_policy>
> > > >::get() Line 89 + 0x16 C++
         basic.exe!boost::spirit::impl::get_definition<smtp_client::impl::grammars::greeting_response,boost::spirit::parser_context<boost::spirit::nil_t>,boost::spirit::scanner<char
*,boost::spirit::scanner_policies<boost::spirit::iteration_policy,boost::spirit::match_policy,boost::spirit::action_policy>
> >(const boost::spirit::grammar<smtp_client::impl::grammars::greeting_response,boost::spirit::parser_context<boost::spirit::nil_t>
> * self=0x005a6664) Line 226 + 0xa C++
         basic.exe!boost::spirit::impl::grammar_parser_parse<0,smtp_client::impl::grammars::greeting_response,boost::spirit::parser_context<boost::spirit::nil_t>,boost::spirit::scanner<char
*,boost::spirit::scanner_policies<boost::spirit::iteration_policy,boost::spirit::match_policy,boost::spirit::action_policy>
> >(const boost::spirit::grammar<smtp_client::impl::grammars::greeting_response,boost::spirit::parser_context<boost::spirit::nil_t>
> * self=0x005a6664, const boost::spirit::scanner<char
*,boost::spirit::scanner_policies<boost::spirit::iteration_policy,boost::spirit::match_policy,boost::spirit::action_policy>
> & scan={...}) Line 279 + 0x9 C++
         basic.exe!boost::spirit::grammar<smtp_client::impl::grammars::greeting_response,boost::spirit::parser_context<boost::spirit::nil_t>
>::parse_main<boost::spirit::scanner<char
*,boost::spirit::scanner_policies<boost::spirit::iteration_policy,boost::spirit::match_policy,boost::spirit::action_policy>
> >() Line 53 + 0x1f C++
         basic.exe!boost::spirit::grammar<smtp_client::impl::grammars::greeting_response,boost::spirit::parser_context<boost::spirit::nil_t>
>::parse<boost::spirit::scanner<char
*,boost::spirit::scanner_policies<boost::spirit::iteration_policy,boost::spirit::match_policy,boost::spirit::action_policy>
> >() Line 63 + 0x42 C++
         basic.exe!boost::spirit::parse<char
*,smtp_client::impl::grammars::greeting_response>(char * const &
first_=0x006e4374, char * const & last=0x006e439a, const
boost::spirit::parser<smtp_client::impl::grammars::greeting_response>
& p={...}) Line 30 C++
         basic.exe!smtp_client::impl::detail::initialize_smtp_connection::match<char
*,smtp_client::impl::grammars::greeting_response>() Line 34 +
0x15 C++
         basic.exe!smtp_client::impl::detail::initialize_smtp_connection::handle_greetings_read(boost::asio::error
& error={...}, unsigned int bytes_received=38) Line 61 + 0x2b C++
         basic.exe!boost::_mfi::mf2<void,smtp_client::impl::detail::initialize_smtp_connection,boost::asio::error
&,unsigned int>::operator()(smtp_client::impl::detail::initialize_smtp_connection
* p=0x006e42c8, boost::asio::error & a1={...}, unsigned int a2=38)
Line 274 + 0x12 C++
         basic.exe!boost::_bi::list3<boost::_bi::value<smtp_client::impl::detail::initialize_smtp_connection
*>,boost::arg<1>,boost::arg<2>
>::operator()<boost::_mfi::mf2<void,smtp_client::impl::detail::initialize_smtp_connection,boost::asio::error
&,unsigned int>,boost::_bi::list2<boost::asio::error &,unsigned int &>
>() Line 348 C++
         basic.exe!boost::_bi::bind_t<void,boost::_mfi::mf2<void,smtp_client::impl::detail::initialize_smtp_connection,boost::asio::error
&,unsigned int>,boost::_bi::list3<boost::_bi::value<smtp_client::impl::detail::initialize_smtp_connection
*>,boost::arg<1>,boost::arg<2> >
>::operator()<boost::asio::error,unsigned int>() Line 62 C++
         basic.exe!boost::detail::function::void_function_obj_invoker2<boost::_bi::bind_t<void,boost::_mfi::mf2<void,smtp_client::impl::detail::initialize_smtp_connection,boost::asio::error
&,unsigned int>,boost::_bi::list3<boost::_bi::value<smtp_client::impl::detail::initialize_smtp_connection
*>,boost::arg<1>,boost::arg<2> > >,void,boost::asio::error,unsigned
int>::invoke(boost::detail::function::function_buffer &
function_obj_ptr={...}, boost::asio::error a0={...}, unsigned int
a1=38) Line 146 C++
         basic.exe!boost::function2<void,boost::asio::error,unsigned
int,_STL::allocator<void> >::operator()(boost::asio::error a0={...},
unsigned int a1=38) Line 682 + 0x2d C++
         basic.exe!smtp_client::smtp_connection::handle_read(boost::asio::error
& error={...}, unsigned int bytes_readed=38, boost::function<void
__cdecl(boost::asio::error,unsigned int),_STL::allocator<void> >
handler={...}) Line 48 C++
         basic.exe!boost::_mfi::mf3<void,smtp_client::smtp_connection,boost::asio::error
&,unsigned int,boost::function<void
__cdecl(boost::asio::error,unsigned int),_STL::allocator<void> >
>::operator()(smtp_client::smtp_connection * p=0x006d85b0,
boost::asio::error & a1={...}, unsigned int a2=38,
boost::function<void __cdecl(boost::asio::error,unsigned
int),_STL::allocator<void> > a3={...}) Line 384 + 0x24 C++
         basic.exe!boost::_bi::list4<boost::_bi::value<smtp_client::smtp_connection
*>,boost::arg<1>,boost::arg<2>,boost::_bi::value<boost::function<void
__cdecl(boost::asio::error,unsigned int),_STL::allocator<void> > >
>::operator()<boost::_mfi::mf3<void,smtp_client::smtp_connection,boost::asio::error
&,unsigned int,boost::function<void
__cdecl(boost::asio::error,unsigned int),_STL::allocator<void> >
>,boost::_bi::list2<boost::asio::error &,unsigned int &> >() Line
413 C++
         basic.exe!boost::_bi::bind_t<void,boost::_mfi::mf3<void,smtp_client::smtp_connection,boost::asio::error
&,unsigned int,boost::function<void
__cdecl(boost::asio::error,unsigned int),_STL::allocator<void> >
>,boost::_bi::list4<boost::_bi::value<smtp_client::smtp_connection
*>,boost::arg<1>,boost::arg<2>,boost::_bi::value<boost::function<void
__cdecl(boost::asio::error,unsigned int),_STL::allocator<void> > > >
>::operator()<boost::asio::error,unsigned int>() Line 62 C++
         basic.exe!boost::asio::detail::win_iocp_socket_service<_STL::allocator<void>
>::receive_operation<boost::_bi::bind_t<void,boost::_mfi::mf3<void,smtp_client::smtp_connection,boost::asio::error
&,unsigned int,boost::function<void
__cdecl(boost::asio::error,unsigned int),_STL::allocator<void> >
>,boost::_bi::list4<boost::_bi::value<smtp_client::smtp_connection
*>,boost::arg<1>,boost::arg<2>,boost::_bi::value<boost::function<void
__cdecl(boost::asio::error,unsigned int),_STL::allocator<void> > > > >
>::do_completion_impl(boost::asio::detail::win_iocp_operation *
op=0x006e45a8, unsigned long last_error=0, unsigned int
bytes_transferred=38) Line 562 C++
         basic.exe!boost::asio::detail::win_iocp_operation::do_completion()
Line 59 + 0x14
         basic.exe!boost::asio::detail::win_iocp_demuxer_service::run() Line 104
         basic.exe!boost::asio::demuxer_service<_STL::allocator<void>
>::run() Line 87
         basic.exe!boost::asio::basic_demuxer<boost::asio::demuxer_service<_STL::allocator<void>
> >::run() Line 107
         basic.exe!_main() Line 62
         basic.exe!mainCRTStartup() Line 259 + 0x19 C
         kernel32.dll!77e523cd()

As you can see, the problem is within get_slots, exactly on this line:

#if defined(BOOST_HAS_WINTHREADS)
    slots = static_cast<tss_slots*>(
        TlsGetValue(tss_data->native_key));

The disassembler shows me:

#if defined(BOOST_HAS_WINTHREADS)
    slots = static_cast<tss_slots*>(
        TlsGetValue(tss_data->native_key));
004DE3D9 mov eax,dword ptr [tss_data (5A8608h)]
004DE3DE mov ecx,dword ptr [eax+20h]
004DE3E1 push ecx
004DE3E2 call dword ptr [__imp__TlsGetValue_at_4 (5AB3B8h)]

And failing on the 004DE3DE with an access to 0x00000020. Which means
that it is reading tss_data as being 0.
This is being executed inside a parsing of a spirit grammar.
A static grammar that's accessed by two threads (on a dual core CPU).

It always strikes on the last "job".
I'm using asio and create 100 sockets, connect them to a SMTP and
start receiving and sending SMTP commands (using spirit to parse the
responses).
Everything is done asynchronously and the demuxer is executed by two threads.
I'm not very sure why tss_data is being seen as 0, and more strangely
in the last message. But prior any returning thread. (The main joins
the second thread, but is always the main thread that hits this).

Any help would be greatly appreciated,
Thanks in advance,

--
Felipe Magno de Almeida

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk