boost,coroutine2(1.63.0):抛出异常使32位窗口上的visual studio崩溃

时间:2017-10-04 14:09:42

标签: c++ visual-studio boost boost-coroutine2

在我的应用程序中,我正在使用coroutine2来生成一些我必须从流中解码的对象。这些对象是使用协同程序生成的。我的问题是,一旦我到达流的末尾,理论上会抛出std :: ios_base :: failure,我的应用程序在某些条件下崩溃。

提供此功能的功能在C ++中实现,作为C函数导出并从C#调用。这一切都发生在Windows 10 x64上的32位进程上。不幸的是,当我在调试模式下从C#开始我的测试时,它只能可靠地崩溃而没有连接本机调试器。一旦我附加本机调试器,一切都会像预期的那样工作。

这是一个重现此问题的小型测试应用程序:

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");
        }
    }
}

一些细节:

  • 我们正在使用Visual Studio 2015 14并动态链接c ++运行时。
  • 测试库静态链接Boost 1.63.0。
  • 我们还试图通过直接从c ++和python调用functionallity来重现这种行为。到目前为止,这两项测试都没有成功。
  • 如果用CTRL F5启动c#代码(意思是没有.net调试器),一切都会好的。只有当您使用F5(意味着附带.NET调试器)启动它时,Visual Studio实例才会崩溃。另外一定不要启用本机调试器!
  • 注意:如果我们不在流中使用例外,那么一切接缝也都可以。不幸的是,解码我的对象的代码使用它们,因此我无法避免这种情况。

如果您对此处可能出现的问题或解决方案有一些额外的提示,那将是惊人的。我不完全确定这是否是一个提升错误,也可能是c#调试器干扰了boost-context。

提前致谢!最诚挚的问候,迈克尔

2 个答案:

答案 0 :(得分:1)

我意识到这个问题很老,但是我刚刚读完the docs中似乎相关的一行:

  

使用fcontext_t的Windows:关闭全局程序优化(/ GL)并将/ EHsc(编译器假定声明为extern“ C”的函数从不抛出C ++异常)更改为/ EHs(tell编译器假定声明为extern“的函数” C”可能会引发异常。

答案 1 :(得分:-1)

这只是一个猜测,但在你的协程中我认为你应该将一个布尔值推送到你的接收器(在你的代码中命名为yield)并且代码没有这样做。