chriskohlhoff / asio

Asio C++ Library
http://think-async.com/Asio
4.85k stars 1.21k forks source link

Same executable, produced by MinGW, handles exceptions from coroutines differently, being run in Wine and native Windows #1068

Open ntff opened 2 years ago

ntff commented 2 years ago

I build my example test.cc:

#include <boost/asio.hpp>                                                        
#include <boost/asio/spawn.hpp>                                                  

#include <iostream>                                                              
#include <stdexcept>                                                             

int                                                                              
main(int argc, char* argv[])                                                     
{                                                                                
    boost::asio::io_context ioc;                                                 

    try                                                                          
    {                                                                            
        boost::asio::spawn(ioc, [&](auto yc)                                     
        {                                                                        
            try                                                                  
            {                                                                    
                throw std::logic_error("le");                                    
            }                                                                    
            catch (...)                                                          
            {                                                                    
                std::cout << "caught at " << __LINE__ << '\n';                   
            }                                                                    
        });                                                                      
        ioc.run();                                                               
    }                                                                            
    catch (...)                                                                  
    {                                                                            
        std::cout << "caught at " << __LINE__ << '\n';                           
    }                                                                            
    return 0;                                                                    
}

, using MinGW (on Linux build station) into test.exe.

I run it on native windows and get output:

caught at 22

, which matches my expectations.

I run it using wine:

$ wine ./test.exe

and get output:

terminate called after throwing an instance of 'std::logic_error'

abnormal program termination

, and it looks wrong for me. This is my problem.

The same code, being compiled for Linux, produces the same output as native Windows.

Also, the simple program that only throws an exception and catches it immediately behaves everywhere the same way (Linux, Wine, Native Windows) - simple exception handling works.

Am I doing something wrong? Missing some compiler parameters? Can it be the problem in Boost code? Can it be a problem in MinGW compiler? Can it be a problem in Wine emulator?

Thank you for any ideas.

My Linux station has the following software:

$ uname -a
Linux vagrant 5.10.0-14-amd64 #1 SMP Debian 5.10.113-1 (2022-04-29) x86_64 GNU/Linux
$ /usr/bin/x86_64-w64-mingw32-g++-posix --version
x86_64-w64-mingw32-g++-posix (GCC) 10-posix 20210110
$ dpkg -l | grep " g++-mingw-w64 "
ii  g++-mingw-w64           10.2.1-6+24.2       all          GNU C++ compiler for MinGW-w64
$ wine --version
wine-5.0.3 (Debian 5.0.3-3)

My native windows is Windows 10.

I build Boost lib from https://conan.io/center/boost recipe with MinGW.

I reduced my build process to the following test.sh script:

#!/bin/sh

#BOOST_HOME=~/.conan/data/boost/1.79.0/_/_/package/0dfdb6daf30fb30a61d87d1f67c5e74535fe1679

BOOST_INCLUDE=${BOOST_HOME}/include
BOOST_LIB=${BOOST_HOME}/lib

rm -f test.exe

/usr/bin/x86_64-w64-mingw32-g++-posix \
    -m64 \
    -std=gnu++2a \
    -D_GLIBCXX_USE_CXX11_ABI=1 \
    test.cc \
    -I${BOOST_INCLUDE} \
    -L${BOOST_LIB} \
    -lboost_coroutine -lboost_context  \
    -lws2_32  \
    -lwinpthread \
    -static -static-libstdc++ -static-libgcc \
    -o test.exe

WINEPATH= wine ./test.exe
ntff commented 2 years ago

I could build my executable for Win32, and it works being run with Wine32. Everything is quite the same, only target platform is different. This solution solves my task and Win64 problem is not a priority for me now.