c++visual-studioboostboost-coroutine2

boost, coroutine2 (1.63.0): throwing exception crashes visual studio on 32bit windows


In my application I'm using coroutine2 to generate some objects which I have to decode from a stream. These objects are generated using coroutines. My problem is that as soon as I reach the end of the stream and would theoretically throw std::ios_base::failure my application crashes under certain conditions.

The function providing this feature is implemented in C++, exported as a C function and called from C#. This all happens on a 32bit process on Windows 10 x64. Unfortunately it only reliably crashes when I start my test from C# in debugging mode WITHOUT the native debugger attached. As soon as I attach the native debugger everything works like expected.

Here is a small test application to reproduce this issue:

Api.h

#pragma once
extern "C" __declspec(dllexport) int __cdecl test();

Api.cpp

#include <iostream>
#include <vector>
#include <sstream>
#include "Api.h"

#define BOOST_COROUTINES2_SOURCE
#include <boost/coroutine2/coroutine.hpp>

int test()
{
    using coro_t = boost::coroutines2::coroutine<bool>;

    coro_t::pull_type source([](coro_t::push_type& yield) {
        std::vector<char> buffer(200300, 0);
        std::stringstream stream;
        stream.write(buffer.data(), buffer.size());

        stream.exceptions(std::ios_base::eofbit | std::ios_base::badbit | std::ios_base::failbit);

        try {
            std::vector<char> dest(100100, 0);
            while (stream.good() && !stream.eof()) {
                stream.read(&dest[0], dest.size());
                std::cerr << "CORO: read: " << stream.gcount() << std::endl;
           }
        }
        catch (const std::exception& ex) {
            std::cerr << "CORO: caught ex: " << ex.what() << std::endl;
        }
        catch (...) {
            std::cerr << "CORO: caught unknown exception." << std::endl;
        }
    });

    std::cout << "SUCCESS" << std::endl;
    return 0;
}

C#:

using System;
using System.Runtime.InteropServices;
namespace CoroutinesTest
{
    class Program
    {
        [DllImport("Api.dll", EntryPoint = "test", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        internal static extern Int32 test();

        static void Main(string[] args)
        {
            test();
            Console.WriteLine("SUCCESS");
        }
    }
}

Some details:

It would be amazing if you had some additional hints on what might go wrong here or a solution. I'm not entirely sure if this is a boost bug, could also be the c# debugger interfering with boost-context.

Thanks in advance! Best Regards, Michael


Solution

  • I realize this question is old but I just finished reading a line in the docs that seemed pertinent:

    Windows using fcontext_t: turn off global program optimization (/GL) and change /EHsc (compiler assumes that functions declared as extern "C" never throw a C++ exception) to /EHs (tells compiler assumes that functions declared as extern "C" may throw an exception).