Exceptions in boost::iostreams::multichar_input_filter disappear when code is compiled with Visual Studio












0















I'm working on a stream filter that can decode a custom file format. My goal is to use boost::iostreams::filtering_istream to read the file and process it with my boost::iostreams::multichar_input_filter subclass, so that I can load values using the << operator.



I also want the process to be terminated when my filter cannot decode the stream and throws an exception, which happens when I compile the code using gcc 5.4 on Windows Subsystem for Linux, but the exception gets swallowed before it reaches my code if I compile with VS2017.



I'm using Boost 1.68.0 on both Windows and WSL; I've built and installed it using b2 on both platforms, without any custom arguments or config. I've also tried 1.58.0 on WSL, which comes from the package manager.



The project uses CMake, and I haven't customised anything in CMakeSettings.json or in launch.vs.json.



I've created this simplified code that shows how I use the filter chain, the exception class, and how I try to catch a processing error:



#include <iostream>
#include <boost/iostreams/concepts.hpp> // multichar_input_filter
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/device/array.hpp>
#include <boost/throw_exception.hpp>

using namespace std;
namespace io = boost::iostreams;

class TestFilterException : public BOOST_IOSTREAMS_FAILURE {
public:
explicit TestFilterException(const char* message) : BOOST_IOSTREAMS_FAILURE(message) {
}
};

class TestFilter : public io::multichar_input_filter {
public:
explicit TestFilter() {
}

template <typename Source> streamsize read(Source& src, char* output_buffer, streamsize requested_char_count) {
BOOST_THROW_EXCEPTION(TestFilterException("Something went wrong"));
}

template <typename Source> void close(Source&) {
}
};

int main(const int argc, const char *argv) {
char buffer[64] = {'x'};
io::array_source source = io::array_source(buffer);

io::filtering_istream in;
in.push(TestFilter());
in.push(source);

char c;
try {
in >> c;
cout << c;
} catch (boost::exception& e) {
cout << "Expected exception";
return 1;
}
return 0;
}


I would expect this code to write the 'Expected exception' message to the output and exit with return code 1 on all platforms. However, when I compile it with Visual Studio, it outputs some garbage and returns code 0.










share|improve this question























  • Check the value of BOOST_EXCEPTION_DISABLE in boost/throw_exception.hpp - maybe it is disabled in Visual Studio. See boost.org/doc/libs/1_50_0/libs/exception/doc/…

    – Rudolfs Bundulis
    Jan 18 at 12:38











  • this code does not print exception using gcc either. Have you tried debugging it to figure out how exception is thrown?

    – VTT
    Jan 18 at 12:48











  • @RudolfsBundulis: Strangely, I cannot open boost/throw_exception.hpp when I ctrl+click on the include line (the build runs fine), so I cannot check the current values of the macros there, but as I'm using msvc 14.1, it should not default to BOOST_EXCEPTION_DISABLE.

    – awagner
    Jan 18 at 13:07











  • @VTT Strange, if I switch to gcc 5.4 with Boost 1.68, it behaves differently: wandbox.org/permlink/5SOtAvgOLzsFagVV

    – awagner
    Jan 18 at 13:11











  • @RudolfsBundulis using #ifdef BOOST_EXCEPTION_DISABLE in my code shows that it's undefined, and the debugger cannot break on the line inside that block.

    – awagner
    Jan 18 at 13:15
















0















I'm working on a stream filter that can decode a custom file format. My goal is to use boost::iostreams::filtering_istream to read the file and process it with my boost::iostreams::multichar_input_filter subclass, so that I can load values using the << operator.



I also want the process to be terminated when my filter cannot decode the stream and throws an exception, which happens when I compile the code using gcc 5.4 on Windows Subsystem for Linux, but the exception gets swallowed before it reaches my code if I compile with VS2017.



I'm using Boost 1.68.0 on both Windows and WSL; I've built and installed it using b2 on both platforms, without any custom arguments or config. I've also tried 1.58.0 on WSL, which comes from the package manager.



The project uses CMake, and I haven't customised anything in CMakeSettings.json or in launch.vs.json.



I've created this simplified code that shows how I use the filter chain, the exception class, and how I try to catch a processing error:



#include <iostream>
#include <boost/iostreams/concepts.hpp> // multichar_input_filter
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/device/array.hpp>
#include <boost/throw_exception.hpp>

using namespace std;
namespace io = boost::iostreams;

class TestFilterException : public BOOST_IOSTREAMS_FAILURE {
public:
explicit TestFilterException(const char* message) : BOOST_IOSTREAMS_FAILURE(message) {
}
};

class TestFilter : public io::multichar_input_filter {
public:
explicit TestFilter() {
}

template <typename Source> streamsize read(Source& src, char* output_buffer, streamsize requested_char_count) {
BOOST_THROW_EXCEPTION(TestFilterException("Something went wrong"));
}

template <typename Source> void close(Source&) {
}
};

int main(const int argc, const char *argv) {
char buffer[64] = {'x'};
io::array_source source = io::array_source(buffer);

io::filtering_istream in;
in.push(TestFilter());
in.push(source);

char c;
try {
in >> c;
cout << c;
} catch (boost::exception& e) {
cout << "Expected exception";
return 1;
}
return 0;
}


I would expect this code to write the 'Expected exception' message to the output and exit with return code 1 on all platforms. However, when I compile it with Visual Studio, it outputs some garbage and returns code 0.










share|improve this question























  • Check the value of BOOST_EXCEPTION_DISABLE in boost/throw_exception.hpp - maybe it is disabled in Visual Studio. See boost.org/doc/libs/1_50_0/libs/exception/doc/…

    – Rudolfs Bundulis
    Jan 18 at 12:38











  • this code does not print exception using gcc either. Have you tried debugging it to figure out how exception is thrown?

    – VTT
    Jan 18 at 12:48











  • @RudolfsBundulis: Strangely, I cannot open boost/throw_exception.hpp when I ctrl+click on the include line (the build runs fine), so I cannot check the current values of the macros there, but as I'm using msvc 14.1, it should not default to BOOST_EXCEPTION_DISABLE.

    – awagner
    Jan 18 at 13:07











  • @VTT Strange, if I switch to gcc 5.4 with Boost 1.68, it behaves differently: wandbox.org/permlink/5SOtAvgOLzsFagVV

    – awagner
    Jan 18 at 13:11











  • @RudolfsBundulis using #ifdef BOOST_EXCEPTION_DISABLE in my code shows that it's undefined, and the debugger cannot break on the line inside that block.

    – awagner
    Jan 18 at 13:15














0












0








0








I'm working on a stream filter that can decode a custom file format. My goal is to use boost::iostreams::filtering_istream to read the file and process it with my boost::iostreams::multichar_input_filter subclass, so that I can load values using the << operator.



I also want the process to be terminated when my filter cannot decode the stream and throws an exception, which happens when I compile the code using gcc 5.4 on Windows Subsystem for Linux, but the exception gets swallowed before it reaches my code if I compile with VS2017.



I'm using Boost 1.68.0 on both Windows and WSL; I've built and installed it using b2 on both platforms, without any custom arguments or config. I've also tried 1.58.0 on WSL, which comes from the package manager.



The project uses CMake, and I haven't customised anything in CMakeSettings.json or in launch.vs.json.



I've created this simplified code that shows how I use the filter chain, the exception class, and how I try to catch a processing error:



#include <iostream>
#include <boost/iostreams/concepts.hpp> // multichar_input_filter
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/device/array.hpp>
#include <boost/throw_exception.hpp>

using namespace std;
namespace io = boost::iostreams;

class TestFilterException : public BOOST_IOSTREAMS_FAILURE {
public:
explicit TestFilterException(const char* message) : BOOST_IOSTREAMS_FAILURE(message) {
}
};

class TestFilter : public io::multichar_input_filter {
public:
explicit TestFilter() {
}

template <typename Source> streamsize read(Source& src, char* output_buffer, streamsize requested_char_count) {
BOOST_THROW_EXCEPTION(TestFilterException("Something went wrong"));
}

template <typename Source> void close(Source&) {
}
};

int main(const int argc, const char *argv) {
char buffer[64] = {'x'};
io::array_source source = io::array_source(buffer);

io::filtering_istream in;
in.push(TestFilter());
in.push(source);

char c;
try {
in >> c;
cout << c;
} catch (boost::exception& e) {
cout << "Expected exception";
return 1;
}
return 0;
}


I would expect this code to write the 'Expected exception' message to the output and exit with return code 1 on all platforms. However, when I compile it with Visual Studio, it outputs some garbage and returns code 0.










share|improve this question














I'm working on a stream filter that can decode a custom file format. My goal is to use boost::iostreams::filtering_istream to read the file and process it with my boost::iostreams::multichar_input_filter subclass, so that I can load values using the << operator.



I also want the process to be terminated when my filter cannot decode the stream and throws an exception, which happens when I compile the code using gcc 5.4 on Windows Subsystem for Linux, but the exception gets swallowed before it reaches my code if I compile with VS2017.



I'm using Boost 1.68.0 on both Windows and WSL; I've built and installed it using b2 on both platforms, without any custom arguments or config. I've also tried 1.58.0 on WSL, which comes from the package manager.



The project uses CMake, and I haven't customised anything in CMakeSettings.json or in launch.vs.json.



I've created this simplified code that shows how I use the filter chain, the exception class, and how I try to catch a processing error:



#include <iostream>
#include <boost/iostreams/concepts.hpp> // multichar_input_filter
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/device/array.hpp>
#include <boost/throw_exception.hpp>

using namespace std;
namespace io = boost::iostreams;

class TestFilterException : public BOOST_IOSTREAMS_FAILURE {
public:
explicit TestFilterException(const char* message) : BOOST_IOSTREAMS_FAILURE(message) {
}
};

class TestFilter : public io::multichar_input_filter {
public:
explicit TestFilter() {
}

template <typename Source> streamsize read(Source& src, char* output_buffer, streamsize requested_char_count) {
BOOST_THROW_EXCEPTION(TestFilterException("Something went wrong"));
}

template <typename Source> void close(Source&) {
}
};

int main(const int argc, const char *argv) {
char buffer[64] = {'x'};
io::array_source source = io::array_source(buffer);

io::filtering_istream in;
in.push(TestFilter());
in.push(source);

char c;
try {
in >> c;
cout << c;
} catch (boost::exception& e) {
cout << "Expected exception";
return 1;
}
return 0;
}


I would expect this code to write the 'Expected exception' message to the output and exit with return code 1 on all platforms. However, when I compile it with Visual Studio, it outputs some garbage and returns code 0.







c++ visual-c++ boost boost-iostreams






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Jan 18 at 12:29









awagnerawagner

284




284













  • Check the value of BOOST_EXCEPTION_DISABLE in boost/throw_exception.hpp - maybe it is disabled in Visual Studio. See boost.org/doc/libs/1_50_0/libs/exception/doc/…

    – Rudolfs Bundulis
    Jan 18 at 12:38











  • this code does not print exception using gcc either. Have you tried debugging it to figure out how exception is thrown?

    – VTT
    Jan 18 at 12:48











  • @RudolfsBundulis: Strangely, I cannot open boost/throw_exception.hpp when I ctrl+click on the include line (the build runs fine), so I cannot check the current values of the macros there, but as I'm using msvc 14.1, it should not default to BOOST_EXCEPTION_DISABLE.

    – awagner
    Jan 18 at 13:07











  • @VTT Strange, if I switch to gcc 5.4 with Boost 1.68, it behaves differently: wandbox.org/permlink/5SOtAvgOLzsFagVV

    – awagner
    Jan 18 at 13:11











  • @RudolfsBundulis using #ifdef BOOST_EXCEPTION_DISABLE in my code shows that it's undefined, and the debugger cannot break on the line inside that block.

    – awagner
    Jan 18 at 13:15



















  • Check the value of BOOST_EXCEPTION_DISABLE in boost/throw_exception.hpp - maybe it is disabled in Visual Studio. See boost.org/doc/libs/1_50_0/libs/exception/doc/…

    – Rudolfs Bundulis
    Jan 18 at 12:38











  • this code does not print exception using gcc either. Have you tried debugging it to figure out how exception is thrown?

    – VTT
    Jan 18 at 12:48











  • @RudolfsBundulis: Strangely, I cannot open boost/throw_exception.hpp when I ctrl+click on the include line (the build runs fine), so I cannot check the current values of the macros there, but as I'm using msvc 14.1, it should not default to BOOST_EXCEPTION_DISABLE.

    – awagner
    Jan 18 at 13:07











  • @VTT Strange, if I switch to gcc 5.4 with Boost 1.68, it behaves differently: wandbox.org/permlink/5SOtAvgOLzsFagVV

    – awagner
    Jan 18 at 13:11











  • @RudolfsBundulis using #ifdef BOOST_EXCEPTION_DISABLE in my code shows that it's undefined, and the debugger cannot break on the line inside that block.

    – awagner
    Jan 18 at 13:15

















Check the value of BOOST_EXCEPTION_DISABLE in boost/throw_exception.hpp - maybe it is disabled in Visual Studio. See boost.org/doc/libs/1_50_0/libs/exception/doc/…

– Rudolfs Bundulis
Jan 18 at 12:38





Check the value of BOOST_EXCEPTION_DISABLE in boost/throw_exception.hpp - maybe it is disabled in Visual Studio. See boost.org/doc/libs/1_50_0/libs/exception/doc/…

– Rudolfs Bundulis
Jan 18 at 12:38













this code does not print exception using gcc either. Have you tried debugging it to figure out how exception is thrown?

– VTT
Jan 18 at 12:48





this code does not print exception using gcc either. Have you tried debugging it to figure out how exception is thrown?

– VTT
Jan 18 at 12:48













@RudolfsBundulis: Strangely, I cannot open boost/throw_exception.hpp when I ctrl+click on the include line (the build runs fine), so I cannot check the current values of the macros there, but as I'm using msvc 14.1, it should not default to BOOST_EXCEPTION_DISABLE.

– awagner
Jan 18 at 13:07





@RudolfsBundulis: Strangely, I cannot open boost/throw_exception.hpp when I ctrl+click on the include line (the build runs fine), so I cannot check the current values of the macros there, but as I'm using msvc 14.1, it should not default to BOOST_EXCEPTION_DISABLE.

– awagner
Jan 18 at 13:07













@VTT Strange, if I switch to gcc 5.4 with Boost 1.68, it behaves differently: wandbox.org/permlink/5SOtAvgOLzsFagVV

– awagner
Jan 18 at 13:11





@VTT Strange, if I switch to gcc 5.4 with Boost 1.68, it behaves differently: wandbox.org/permlink/5SOtAvgOLzsFagVV

– awagner
Jan 18 at 13:11













@RudolfsBundulis using #ifdef BOOST_EXCEPTION_DISABLE in my code shows that it's undefined, and the debugger cannot break on the line inside that block.

– awagner
Jan 18 at 13:15





@RudolfsBundulis using #ifdef BOOST_EXCEPTION_DISABLE in my code shows that it's undefined, and the debugger cannot break on the line inside that block.

– awagner
Jan 18 at 13:15












1 Answer
1






active

oldest

votes


















1














I think it is a bug in the older gcc. Newer gcc and VS correctly catch exception thrown and set bad bit flag instead of propagating exception through stream methods. Garbage is printed because c is left uninitialized after a failed read attempt. You can make stream throw a bad bit exception by setting exception flags in the stream:



try
{
io::filtering_istream in;
in.exceptions(::std::ios_base::badbit | ::std::ios_base::failbit | ::std::ios_base::eofbit);
in.push(TestFilter());
in.push(source);
char c;
in >> c;
cout << c;
} catch (boost::exception& e) {
cout << "not expected boost exception";
return 1;
}
catch(::std::exception const & e)
{
cout << "Expected std exception";
return 2;
}


also see iostream Exceptions documentation






share|improve this answer


























  • Thank you, adding in.exceptions(ios_base::badbit); to my code resolved the issue. I can now catch (const boost::exception& e), and see the original error message with e.what(). I've read the linked documentation page earlier but didn't understand how and when should be the exception mask used, or if it was required at all for my usecase.

    – awagner
    Jan 18 at 14:10











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54254063%2fexceptions-in-boostiostreamsmultichar-input-filter-disappear-when-code-is-co%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














I think it is a bug in the older gcc. Newer gcc and VS correctly catch exception thrown and set bad bit flag instead of propagating exception through stream methods. Garbage is printed because c is left uninitialized after a failed read attempt. You can make stream throw a bad bit exception by setting exception flags in the stream:



try
{
io::filtering_istream in;
in.exceptions(::std::ios_base::badbit | ::std::ios_base::failbit | ::std::ios_base::eofbit);
in.push(TestFilter());
in.push(source);
char c;
in >> c;
cout << c;
} catch (boost::exception& e) {
cout << "not expected boost exception";
return 1;
}
catch(::std::exception const & e)
{
cout << "Expected std exception";
return 2;
}


also see iostream Exceptions documentation






share|improve this answer


























  • Thank you, adding in.exceptions(ios_base::badbit); to my code resolved the issue. I can now catch (const boost::exception& e), and see the original error message with e.what(). I've read the linked documentation page earlier but didn't understand how and when should be the exception mask used, or if it was required at all for my usecase.

    – awagner
    Jan 18 at 14:10
















1














I think it is a bug in the older gcc. Newer gcc and VS correctly catch exception thrown and set bad bit flag instead of propagating exception through stream methods. Garbage is printed because c is left uninitialized after a failed read attempt. You can make stream throw a bad bit exception by setting exception flags in the stream:



try
{
io::filtering_istream in;
in.exceptions(::std::ios_base::badbit | ::std::ios_base::failbit | ::std::ios_base::eofbit);
in.push(TestFilter());
in.push(source);
char c;
in >> c;
cout << c;
} catch (boost::exception& e) {
cout << "not expected boost exception";
return 1;
}
catch(::std::exception const & e)
{
cout << "Expected std exception";
return 2;
}


also see iostream Exceptions documentation






share|improve this answer


























  • Thank you, adding in.exceptions(ios_base::badbit); to my code resolved the issue. I can now catch (const boost::exception& e), and see the original error message with e.what(). I've read the linked documentation page earlier but didn't understand how and when should be the exception mask used, or if it was required at all for my usecase.

    – awagner
    Jan 18 at 14:10














1












1








1







I think it is a bug in the older gcc. Newer gcc and VS correctly catch exception thrown and set bad bit flag instead of propagating exception through stream methods. Garbage is printed because c is left uninitialized after a failed read attempt. You can make stream throw a bad bit exception by setting exception flags in the stream:



try
{
io::filtering_istream in;
in.exceptions(::std::ios_base::badbit | ::std::ios_base::failbit | ::std::ios_base::eofbit);
in.push(TestFilter());
in.push(source);
char c;
in >> c;
cout << c;
} catch (boost::exception& e) {
cout << "not expected boost exception";
return 1;
}
catch(::std::exception const & e)
{
cout << "Expected std exception";
return 2;
}


also see iostream Exceptions documentation






share|improve this answer















I think it is a bug in the older gcc. Newer gcc and VS correctly catch exception thrown and set bad bit flag instead of propagating exception through stream methods. Garbage is printed because c is left uninitialized after a failed read attempt. You can make stream throw a bad bit exception by setting exception flags in the stream:



try
{
io::filtering_istream in;
in.exceptions(::std::ios_base::badbit | ::std::ios_base::failbit | ::std::ios_base::eofbit);
in.push(TestFilter());
in.push(source);
char c;
in >> c;
cout << c;
} catch (boost::exception& e) {
cout << "not expected boost exception";
return 1;
}
catch(::std::exception const & e)
{
cout << "Expected std exception";
return 2;
}


also see iostream Exceptions documentation







share|improve this answer














share|improve this answer



share|improve this answer








edited Jan 18 at 13:50

























answered Jan 18 at 13:44









VTTVTT

24.8k42446




24.8k42446













  • Thank you, adding in.exceptions(ios_base::badbit); to my code resolved the issue. I can now catch (const boost::exception& e), and see the original error message with e.what(). I've read the linked documentation page earlier but didn't understand how and when should be the exception mask used, or if it was required at all for my usecase.

    – awagner
    Jan 18 at 14:10



















  • Thank you, adding in.exceptions(ios_base::badbit); to my code resolved the issue. I can now catch (const boost::exception& e), and see the original error message with e.what(). I've read the linked documentation page earlier but didn't understand how and when should be the exception mask used, or if it was required at all for my usecase.

    – awagner
    Jan 18 at 14:10

















Thank you, adding in.exceptions(ios_base::badbit); to my code resolved the issue. I can now catch (const boost::exception& e), and see the original error message with e.what(). I've read the linked documentation page earlier but didn't understand how and when should be the exception mask used, or if it was required at all for my usecase.

– awagner
Jan 18 at 14:10





Thank you, adding in.exceptions(ios_base::badbit); to my code resolved the issue. I can now catch (const boost::exception& e), and see the original error message with e.what(). I've read the linked documentation page earlier but didn't understand how and when should be the exception mask used, or if it was required at all for my usecase.

– awagner
Jan 18 at 14:10


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54254063%2fexceptions-in-boostiostreamsmultichar-input-filter-disappear-when-code-is-co%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Liquibase includeAll doesn't find base path

How to use setInterval in EJS file?

Petrus Granier-Deferre