Boost logo

Boost Users :

Subject: [Boost-users] [boost::asio::serial_port] Calling cancel() causes Run-Time Check Failure #0 on Visual Studio 2010 SP1
From: Dario Ramos (dario_ramos_at_[hidden])
Date: 2012-03-15 08:44:59


This is a fatal error, there's no way to recover from it, and in release
builds, a nasty message box appears. It happens when I call
serial_port::cancel and Boost tries to throw some exception. The exact
error is:

Run-Time Check Failure #0 - The value of ESP was not properly saved across
a function call. This is usually a result of calling a function declared
with one calling convention with a function pointer declared with a
different calling convention.

And it seems to happen in throw_error.ipp, inside the do_throw_error method.
Here's a small sample program which reproduces this:

#include <boost/asio/serial_port.hpp>
#include <boost/asio/read.hpp>
#include <boost/thread.hpp>
#include <iostream>

using namespace std;

BYTE g_pBuffer[128];

void ReadCompletionHandler( boost::system::error_code ec, std::size_t
bytesTransferred ){
if( !ec ){
cout << "Read " << bytesTransferred << " bytes successfully" << endl;
}else if( ec == boost::asio::error::operation_aborted ){
cout << "Aborted async_read_some, " << bytesTransferred << " bytes
transferred" << endl;
}else{
cout << "Read finished with errors: " << ec.message() << endl;
}
}

void ReaderThread( boost::asio::serial_port* pSerialPort ){
cout << "[ReaderThread] Started reading" << endl;
boost::asio::async_read( *pSerialPort, boost::asio::buffer( g_pBuffer, 5 ),
ReadCompletionHandler );
cout << "[ReaderThread] Done!" << endl;
}

void main(){
//Tell cout not to buffer its output so output better reflects
multithreaded execution
std::cout.setf(std::ios::unitbuf);
boost::asio::io_service ioService;
boost::asio::serial_port serialPort( ioService );
string portName = "COM1";
serialPort.open( portName );
if( !serialPort.is_open() ){
cout << "Failed to open " << portName << endl;
return;
}
cout << "Launching reader thread and io_service" << endl;
boost::thread readerThread( boost::bind( ReaderThread, &serialPort ) );
ioService.run();
cout << "Sleeping..." << endl;
::Sleep( 5000 );
cout << "Woke up, cancelling pending reads" << endl;
serialPort.cancel();
cout << "Waiting for reader thread to finish..." << endl;
readerThread.join();
cout << "Done!" << endl;
cin.get();
}

Maybe I'm doing something stupid. What do you think?

-- 
*Darío Eduardo Ramos*
Meditech S.A. www.meditech.com.ar
(+54) 01147603300, Interno 31
Av. Julio A. Roca 3456
Florida Oeste, Bs.As. Argentina


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net