Subject: [Boost-bugs] [Boost C++ Libraries] #7580: boost::asio::tcp SEGV after ioservice stopped, restarted and new
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2012-10-27 12:34:52
#7580: boost::asio::tcp SEGV after ioservice stopped, restarted and new
------------------------------+---------------------------------------------
Reporter: tobi@⦠| Type: Bugs
Status: new | Milestone: To Be Determined
Component: None | Version: Boost 1.50.0
Severity: Problem | Keywords:
------------------------------+---------------------------------------------
For solarpowerlog [1] I use boost::asio for the communication via TCP/IP.
During an implementation of an new feature I experienced an reproducible
segfault when during ioservice->poll()
I hope to give enough information to dig into, but if you need some
additional information, please let me know.
Please let me also know if I am (unknowingly) misuse or use the library
wrongly.
Thanks
coldtobi
'''What I am doing:'''
The feature is for sharing a TCP/IP connection within several data
sources/sinks in the programm. For this implementation every data source
can write and receive at abitrary times where sends have priority over
receives. This is realized in the way that receives are interrupted if
another data source request a write and then the receive is resumed. The
handling of the TCP/IP i/o is done in an dedicated thread (I mark this
"[T]" below) , the interruption in the "main" process (marked [M])
So basically the programm does:
[T] socket->connect()
[T] socket->async_write(); (in parallel running a deadline_timer to catch
timeouts)
[T] socket->read_some(); (in parallel running a deadline_timer to catch
timeouts. Later we will socket->read_some again after we know the amount
of pending bytes. and read those. But for this report: The interruption
(next step) is usually at the first read_some() )
[M] ioservice->stop(); (this aborts the read_some, )
Here the thread making the IO detects that the ioservice has been stopped
via ioservice->stopped() and will then abort the current operation, wait
for the next request adn before executing this new request it will call
ioservice->reset():
[t] ioservice->reset()
As we now close to the crash, I will elabaroate as precise as possible
what is done. (This all now is in the I/O thread)
Note: You can find the code at [3]. I add line numbers for better
orientation
creating the deadline-timer: (lines 684+)
{{{
deadline_timer timer(*(this->ioservice));
boost::posix_time::time_duration td =
boost::posix_time::millisec(timeout);
timer.expires_from_now(td);
timer.async_wait(boost::bind(&boosthelper_set_result, (int*)
&result_timer,
1));
}}}
(boosthelper_set_result is defined in line 451 and just set result_timer
to 1 if called)
write the bytes: (line 692+)
{{{
boost::asio::async_write(*sockt, boost::asio::buffer(s),
write_handler);
}}}
s is a std::string and contains the data to be sent. max 255 bytes ASCII)
run the ioservice once to either finish the write or the timeout (line
695)
{{{
size_t num = ioservice->run_one(ec);
}}}
run_once returns and the evaluation shows that async_write completed
-- num!=0 is checked and the result_timer also
Observation: Wireshark shows that the bytes are not transmitted
Then the timer is cancelled and its completion handler catched: (line
703+)
{{{
timer.cancel();
LOGTRACE(logger, __PRETTY_FUNCTION__ << ": still alive 2f");
ioservice->poll();
LOGTRACE(logger, __PRETTY_FUNCTION__ << ": still alive 3");
}}}
ioservice->poll() is never returning, SEGV is raised here. Unfortunatly
the backtrace is also corrupted.
When not calling the ioservice->stop(), the SEGFAULT is gone too.
(Confirmed by working around the need to stop the ioservice by just
polling with short timeouts)
'''Testcase'''
Providing a destilled testcase is unfortuantly difficult. However, you can
use solarpowerlog to see the issue. I commmited also sample configuration
which allows a easy reproduction of the issue. See the git tree here [2].
If you have debian, you can install the build-dependencies by '''apt-get
build-dep solarpowerlog'''
Otherwise configure will tell you about missing deps :-)
{{{
git clone
git://solarpowerlog.git.sourceforge.net/gitroot/solarpowerlog/solarpowerlog
cd solarpowerlog
git checkout 47c079d3409c867287888f47bedb4f05b1c353b5
./bootstrap.sh
./configure --enable-sharedcomms --enable-sputniksimulator --enable-
dummyinverter
make
# in one shell (this one will not crash)
src/solarpowerlog -c tools/sputnik_simulator/solarpowerlog_shared.conf
# in another shell: (this one which will crash)
src/solarpowerlog -c example_confs/solarpowerlog_shared_sim.conf
}}}
After some seconds youl'll see the SEGV:
{{{
12839 [0x7f2cc3345760] DEBUG
inverter.Simulator2.Comms_SharedConnection.SharedTarget null - virtual
void CSharedConnectionSlave::Send(ICommand*): work: 0x7f2cb8003550
12839 [0x7f2cc3345760] DEBUG
inverter.Simulator2.Comms_SharedConnection.SharedTarget null - Not atomic
0x7f2cb8003550
12839 [0x7f2cc3345760] DEBUG
inverter.Simulator2.Comms_SharedConnection.SharedTarget null - virtual
void CSharedConnectionSlave::Send(ICommand*): submitting work:
0x7f2cb8003550
12839 [0x7f2cc3345760] DEBUG
inverter.Simulator.Comms_SharedConnection..Comms_TCP_ASIO null - virtual
bool CConnectTCPAsio::AbortAll() Aborting 0 backlog entries
12839 [0x7f2cc3345760] DEBUG
inverter.Simulator.Comms_SharedConnection..Comms_TCP_ASIO null - virtual
bool CConnectTCPAsio::AbortAll() Done
12839 [0x7f2cc3345760] DEBUG inverter.Simulator.Comms_SharedConnection.
null - Ticket for this command is: 0 (current ticket is 0)
12839 [0x7f2cc3345760] DEBUG inverter.Simulator.Comms_SharedConnection.
null - CSharedConnectionMaster::Send() ICmd: 0x7f2cb8003550
12964 [0x7f2cbfea1700] TRACE
inverter.Simulator.Comms_SharedConnection..Comms_TCP_ASIO null - ioservice
stopped (1)
12964 [0x7f2cbfea1700] TRACE
inverter.Simulator.Comms_SharedConnection..Comms_TCP_ASIO null - Waiting
for work
12964 [0x7f2cbfea1700] DEBUG
inverter.Simulator.Comms_SharedConnection..Comms_TCP_ASIO null - ioservice
stopped
12964 [0x7f2cbfea1700] TRACE
inverter.Simulator.Comms_SharedConnection..Comms_TCP_ASIO null - void
CConnectTCPAsio::HandleSend(CAsyncCommand*): now handling: 0x7f2cb8003550
12964 [0x7f2cbfea1700] TRACE
inverter.Simulator.Comms_SharedConnection..Comms_TCP_ASIO null - void
CConnectTCPAsio::HandleSend(CAsyncCommand*): still alive 1
12964 [0x7f2cc3345760] DEBUG inverter.Simulator.Comms_SharedConnection.
null - virtual void CSharedConnectionMaster::ExecuteCommand(const
ICommand*) now handling: 0x7f2cb8004460
12964 [0x7f2cbfea1700] TRACE
inverter.Simulator.Comms_SharedConnection..Comms_TCP_ASIO null - void
CConnectTCPAsio::HandleSend(CAsyncCommand*): still alive 2
12964 [0x7f2cc3345760] DEBUG inverter.Simulator.Comms_SharedConnection.
null - virtual void CSharedConnectionMaster::ExecuteCommand(const
ICommand*) rescheduling read: 0x7f2cb8003e30
12964 [0x7f2cbfea1700] TRACE
inverter.Simulator.Comms_SharedConnection..Comms_TCP_ASIO null - void
CConnectTCPAsio::HandleSend(CAsyncCommand*): still alive 2e
12964 [0x7f2cbfea1700] TRACE
inverter.Simulator.Comms_SharedConnection..Comms_TCP_ASIO null - void
CConnectTCPAsio::HandleSend(CAsyncCommand*): still alive 2f
src/solarpowerlog Segmentation fault.
}}}
[1] http://sourceforge.net/projects/solarpowerlog/
[2]
http://solarpowerlog.git.sourceforge.net/git/gitweb.cgi?p=solarpowerlog/solarpowerlog;a=commit;h=47c079d3409c867287888f47bedb4f05b1c353b5
[3]
http://solarpowerlog.git.sourceforge.net/git/gitweb.cgi?p=solarpowerlog/solarpowerlog;a=blob;f=src/Connections/CConnectTCPAsio.cpp;h=5e3b0a1b13b66cc07e491ed98ad7dfe1f3cc5277;hb=47c079d3409c867287888f47bedb4f05b1c353b5
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/7580> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:11 UTC