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

问题描述:

在我的应用程序中,我使用coroutine2来生成一些对象,我必须从流中解码。这些对象是使用协程生成的。我的问题是,只要我到达流的末尾,理论上会抛出std :: ios_base :: failure,在特定条件下我的应用程序崩溃。boost,coroutine2(1.63.0):在32位窗口抛出异常崩溃visual studio

提供此功能的函数在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(意思是没有.net调试器)启动c#代码,一切都会好起来的。只有当你用F5启动它(意味着附加的.NET调试器)时,Visual Studio实例才会崩溃。另外请确保不要启用本地调试器!
  • 注意:如果我们不使用流中的例外,那么所有接缝也都可以。不幸的是,解码我的对象的代码使用它们,因此我无法避免这种情况。

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

在此先感谢!最好的问候,迈克尔

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

+0

这只是为了简化重现问题的示例。 这个问题发生之前,我们甚至得到这么多。协程创建后,尝试执行一些流操作,并在它甚至到达那个之前抛出异常。 – MichaelE1000