Pascal Kesseli
2012-04-23 09:25:56 UTC
Hi everyone
Since having updated to boost version 1.48, I am experiencing severe =
runtime errors when relying on asynchronous operations. Please consider =
=
the following code (the important bit is located in ServerReceive=E2=80=99=
s =
operator() ):
=3D=3D=3D main.cpp =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/write.hpp>
#include <boost/asio/read.hpp>
#include <boost/exception/all.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/thread.hpp>
using namespace boost;
using namespace boost::asio;
using namespace boost::posix_time;
using namespace boost::system;
using namespace std;
namespace {
const char * const CONNECTION_UNAVAILABLE("error.connection-unavailable"=
);
const char * const RESOLVE_ERROR("error.resolve");
struct host_name;
struct port_value;
ip::tcp::endpoint createEndpoint(const string &hostName, unsigned int =
port) {
io_service ioService;
ip::tcp::resolver resolver(ioService);
ip::tcp::resolver::query query(hostName, lexical_cast<string>(port), =
ip::tcp::resolver::query::numeric_service);
try {
ip::tcp::resolver::iterator resolve(resolver.resolve(query));
if (resolve !=3D ip::tcp::resolver::iterator()) {
return *resolve;
}
} catch (...) {
error_info<host_name, string> nameInfo(hostName);
error_info<port_value, unsigned int> portInfo(port);
exception_ptr nested(current_exception());
runtime_error error(RESOLVE_ERROR);
BOOST_THROW_EXCEPTION(enable_error_info(error) << nameInfo << portInfo <=
< =
errinfo_nested_exception(nested));
}
error_info<host_name, string> nameInfo(hostName);
error_info<port_value, unsigned int> portInfo(port);
BOOST_THROW_EXCEPTION(enable_error_info(runtime_error(CONNECTION_UNAVAIL=
ABLE)) =
<< nameInfo << portInfo);
}
class ServerReceive {
private:
volatile bool ready;
string result;
public:
ServerReceive() :
ready(false) {
}
~ServerReceive() {
}
void operator()() {
io_service io;
try {
ip::tcp::socket socket(io);
ip::tcp::acceptor acceptor(io, ip::tcp::endpoint(ip::tcp::v4(), 32768));=
acceptor.listen();
ready =3D true;
acceptor.accept(socket);
char data[] =3D { '\0', '\0', '\0', '\0', '\0' };
// SYNCHRONOUS CALL
read(socket, buffer(data, 4));
// SYNCHRONOUS CALL
result =3D data;
} catch (const std::exception &ex) {
result =3D ex.what();
ready =3D true;
}
}
const string &getResult() const {
return result;
}
volatile bool isReady() const {
return ready;
}
};
}
int main(int argc, char *argv[]) {
ServerReceive serverReceive;
thread server(ref(serverReceive));
while (!serverReceive.isReady()) {
this_thread::sleep(milliseconds(100));
}
io_service io;
ip::tcp::socket socket(io);
socket.connect(createEndpoint("127.0.0.1", 32768));
asio::write(socket, buffer("asdf", 4));
server.join();
cout << "Result: " << serverReceive.getResult() << endl;
}
=3D=3D=3D main.cpp =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
While this example works like a charm:
=3D=3D=3D output =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
***@target:/tmp/sync# ./sync
=E2=80=9CResult: asdf=E2=80=9D
=3D=3D=3D output =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
Using an equivalent asynchronous operation will result in an =E2=80=9Cil=
legal =
instruction=E2=80=9D error:
void onSuccess(const error_code &error, size_t bytes_transferred) {
=3D=3D=3D main.cpp =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
// ...
}
// ...
async_read(socket, buffer(data, 4), &onSuccess);
io.run();
=3D=3D=3D main.cpp =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
=3D=3D=3D output =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
***@target:/tmp/async# ./async
Illegal instruction
=3D=3D=3D output =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
I am compiling the executable with the following gcc 4.4.2 command:
=3D=3D=3D command =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
xscale-linux-g++ -fPIC -DBOOST_ASIO_DISABLE_EPOLL =
-I/var/lib/c++/boost/boost_1_48_0/target/arm-linux-4.4.2/include -oasync=
=
main.cpp =
-L/var/lib/c++/boost/boost_1_48_0/target/arm-linux-4.4.2/lib/static =
-pthread -lboost_system -lboost_thread
=3D=3D=3D command =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
Is this a common or known issue and does anyone have any idea as to how =
to =
address it?
Thanks for any hints and best regards
Pascal
Since having updated to boost version 1.48, I am experiencing severe =
runtime errors when relying on asynchronous operations. Please consider =
=
the following code (the important bit is located in ServerReceive=E2=80=99=
s =
operator() ):
=3D=3D=3D main.cpp =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/write.hpp>
#include <boost/asio/read.hpp>
#include <boost/exception/all.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/thread.hpp>
using namespace boost;
using namespace boost::asio;
using namespace boost::posix_time;
using namespace boost::system;
using namespace std;
namespace {
const char * const CONNECTION_UNAVAILABLE("error.connection-unavailable"=
);
const char * const RESOLVE_ERROR("error.resolve");
struct host_name;
struct port_value;
ip::tcp::endpoint createEndpoint(const string &hostName, unsigned int =
port) {
io_service ioService;
ip::tcp::resolver resolver(ioService);
ip::tcp::resolver::query query(hostName, lexical_cast<string>(port), =
ip::tcp::resolver::query::numeric_service);
try {
ip::tcp::resolver::iterator resolve(resolver.resolve(query));
if (resolve !=3D ip::tcp::resolver::iterator()) {
return *resolve;
}
} catch (...) {
error_info<host_name, string> nameInfo(hostName);
error_info<port_value, unsigned int> portInfo(port);
exception_ptr nested(current_exception());
runtime_error error(RESOLVE_ERROR);
BOOST_THROW_EXCEPTION(enable_error_info(error) << nameInfo << portInfo <=
< =
errinfo_nested_exception(nested));
}
error_info<host_name, string> nameInfo(hostName);
error_info<port_value, unsigned int> portInfo(port);
BOOST_THROW_EXCEPTION(enable_error_info(runtime_error(CONNECTION_UNAVAIL=
ABLE)) =
<< nameInfo << portInfo);
}
class ServerReceive {
private:
volatile bool ready;
string result;
public:
ServerReceive() :
ready(false) {
}
~ServerReceive() {
}
void operator()() {
io_service io;
try {
ip::tcp::socket socket(io);
ip::tcp::acceptor acceptor(io, ip::tcp::endpoint(ip::tcp::v4(), 32768));=
acceptor.listen();
ready =3D true;
acceptor.accept(socket);
char data[] =3D { '\0', '\0', '\0', '\0', '\0' };
// SYNCHRONOUS CALL
read(socket, buffer(data, 4));
// SYNCHRONOUS CALL
result =3D data;
} catch (const std::exception &ex) {
result =3D ex.what();
ready =3D true;
}
}
const string &getResult() const {
return result;
}
volatile bool isReady() const {
return ready;
}
};
}
int main(int argc, char *argv[]) {
ServerReceive serverReceive;
thread server(ref(serverReceive));
while (!serverReceive.isReady()) {
this_thread::sleep(milliseconds(100));
}
io_service io;
ip::tcp::socket socket(io);
socket.connect(createEndpoint("127.0.0.1", 32768));
asio::write(socket, buffer("asdf", 4));
server.join();
cout << "Result: " << serverReceive.getResult() << endl;
}
=3D=3D=3D main.cpp =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
While this example works like a charm:
=3D=3D=3D output =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
***@target:/tmp/sync# ./sync
=E2=80=9CResult: asdf=E2=80=9D
=3D=3D=3D output =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
Using an equivalent asynchronous operation will result in an =E2=80=9Cil=
legal =
instruction=E2=80=9D error:
void onSuccess(const error_code &error, size_t bytes_transferred) {
=3D=3D=3D main.cpp =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
// ...
}
// ...
async_read(socket, buffer(data, 4), &onSuccess);
io.run();
=3D=3D=3D main.cpp =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
=3D=3D=3D output =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
***@target:/tmp/async# ./async
Illegal instruction
=3D=3D=3D output =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
I am compiling the executable with the following gcc 4.4.2 command:
=3D=3D=3D command =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
xscale-linux-g++ -fPIC -DBOOST_ASIO_DISABLE_EPOLL =
-I/var/lib/c++/boost/boost_1_48_0/target/arm-linux-4.4.2/include -oasync=
=
main.cpp =
-L/var/lib/c++/boost/boost_1_48_0/target/arm-linux-4.4.2/lib/static =
-pthread -lboost_system -lboost_thread
=3D=3D=3D command =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
Is this a common or known issue and does anyone have any idea as to how =
to =
address it?
Thanks for any hints and best regards
Pascal