Subject: [Boost-bugs] [Boost C++ Libraries] #13515: async_pipe::async_read_some returns zero read size if -O<something> is used
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2018-04-06 14:20:16
#13515: async_pipe::async_read_some returns zero read size if -O<something> is used
-------------------------------------+----------------------------
Reporter: Tomasz Jonak <tjonak@â¦> | Owner: chris_kohlhoff
Type: Bugs | Status: new
Milestone: To Be Determined | Component: asio
Version: Boost 1.66.0 | Severity: Problem
Keywords: |
-------------------------------------+----------------------------
Hi there,
We are developing coroutine based application which sits mostly on some
sort of I/O. Decided to go with coroutine based approach with boost 1.66
and asio/beast/process libs. While doing some internal POC we ran into
issue with retrieving size of data obtained through pipe.
{{{
#!div style="font-size: 80%"
{{{#!C++
#include <boost/asio.hpp>
#include <boost/asio/spawn.hpp>
#include <boost/process.hpp>
#include <chrono>
#include <iostream>
void test_process()
{
static const char* path = "./dataspit.py";
static const char* interpreter = "python3";
std::cout << "Hello from streamer2\n";
namespace asio = boost::asio;
namespace process = boost::process;
namespace chrono = std::chrono;
asio::io_context ioc;
asio::spawn(ioc,
[&ioc](asio::yield_context yield)
{
process::async_pipe pipe{ioc};
auto child = process::child{process::search_path(interpreter),
path,
process::std_out > pipe};
std::array<char, 4096> buffer{0};
std::cout << "Buffer state: " << (int)buffer[0] << (int)buffer[1]
<< std::endl;
boost::system::error_code read_ec;
do
{
auto timePoint = chrono::system_clock::now();
std::cout << timePoint.time_since_epoch().count() << ":
Sleeping\n";
std::size_t size = pipe.async_read_some(asio::buffer(buffer),
yield[read_ec]);
if (read_ec) {
std::cerr << read_ec.message() << std::endl;
break;
}
timePoint = chrono::system_clock::now();
std::cout << timePoint.time_since_epoch().count() << ": Read "
<< size << " bytes\n";
std::cout << "Buffer state: " << (int)buffer[0] <<
(int)buffer[1] << std::endl;
}
while (read_ec != boost::asio::error::eof);
child.wait();
}
);
ioc.run();
std::cout << "Farewell from streamer2\n";
}
int main(int argc, char** argv)
{
test_process();
return 0;
}
}}}
}}}
This code works fine when no compiler optimizations are used. As soon as
its compiled with -Os or any numbered -O type.
{{{
#!div style="font-size: 80%"
{{{#!C++
pipe.async_read_some(asio::buffer(buffer), yield[read_ec]);
}}}
}}}
starts returning 0. Buffer contents are modified though. Callback based
approach yields same result.
{{{
#!div style="font-size: 80%"
{{{
...
readv(6, [{"57757488835088650590974423544437"..., 4096}], 1) = 1030
write(1, "1523018074402113597: Read 0 byte"..., 341523018074402113597:
Read 0 bytes) = 34
write(1, "Buffer state: 5355\n", 19Buffer state: 5355) = 19
write(1, "1523018074402457408: Sleeping\n", 301523018074402457408:
Sleeping) = 30
readv(6, 0x83c2168, 1) = -1 EAGAIN (Resource temporarily
unavailable)
epoll_wait(4, [{EPOLLIN, {u32=138163408, u64=138163408}}], 128, -1) = 1
readv(6, [{"15827357453760420053575823774839"..., 4096}], 1) = 546
write(1, "1523018076807802498: Read 0 byte"..., 341523018076807802498:
Read 0 bytes) = 34
write(1, "Buffer state: 4953\n", 19Buffer state: 4953) = 19
write(1, "1523018076808233410: Sleeping\n", 301523018076808233410:
Sleeping) = 30
readv(6, 0x83c2168, 1) = -1 EAGAIN (Resource temporarily
unavailable)
epoll_wait(4, [{EPOLLIN, {u32=138163408, u64=138163408}}], 128, -1) = 1
readv(6, [{"66365484273136085944223051047033"..., 4096}], 1) = 814
write(1, "1523018079517434883: Read 0 byte"..., 341523018079517434883:
Read 0 bytes) = 34
write(1, "Buffer state: 5454\n", 19Buffer state: 5454) = 19
write(1, "1523018079517782099: Sleeping\n", 301523018079517782099:
Sleeping) = 30
readv(6, 0x83c2168, 1) = -1 EAGAIN (Resource temporarily
unavailable)
...
}}}
}}}
Epoll waits as expected, readv seems to return length as well. Looks like
some kind of reordering issue.
Tested this behavior on ubuntu 14.04/16.04 in 32/64bit modes on using
stock gcc, all ran in docker containers within ubuntu 16.04 host.
Issue applies to boost 1.66 for sure, tested also 1.65 and 1.67 beta on
ubuntu 14.04 32 bit. Issue is there as well.
Complete sample code in attachments.
I'd be grateful for some notification if you find root cause and possible
patch. I'd like to apply such to our boost sources.
Best Regards,
Tomasz Jonak
-- Ticket URL: <https://svn.boost.org/trac10/ticket/13515> 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 : 2018-04-06 14:27:52 UTC