[ https://issues.apache.org/jira/browse/THRIFT-4781?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17086110#comment-17086110 ]
Andrej Nazarov commented on THRIFT-4781: ---------------------------------------- Hi [~zeshuai007]. Can you attach the code you're using to reproduce the bug (including thrift schema files + thrift cpp library as .lib file)? Ideally as Visual Studio project/solution. I would have sent you my code, but there's a complication - I can't get Thrift C++ library to build on my computer. I tried 0.11 and 0.13. I'm on Windows 10 and I tried using MS VC++ 19.25.28614.0 + CMake 3.17.1 and Visual Studio 2019. h3. CMake GUI 3.17.1 I get an error in Configure stage: {noformat} CMake Error at CMakeLists.txt:21 (include): include could not find load file: BoostMacros CMake Error at CMakeLists.txt:22 (REQUIRE_BOOST_HEADERS): Unknown CMake command "REQUIRE_BOOST_HEADERS". {noformat} Adding this line as first command in CMakeLists.txt: {{find_package(Boost 1.72.0)}} yields this message first: {{Found Boost: C:/libs/boost_1_72_0 (found suitable version "1.72.0", minimum required is "1.72.0")}} but then the same error with BoostMacros appears (now on line 22). h3. Visual Studio 2019 I opened *lib\cpp\thrift.sln* # Upgraded to target toolset to 'v142' (was 'v100') when prompted (v100 = VS2010) # Used these 3rd party libs: ||Name + Version||Include Path||Notes|| |Boost 1.72.0|C:\libs\boost_1_72_0|from [boost.org|https://www.boost.org/users/history/version_1_72_0.html], builds locally fine| |Open SSL 1.1.1f|C:\Program Files\OpenSSL-Win64\include|from [slproweb.com|https://slproweb.com/products/Win32OpenSSL.html], also used {{Program Files (x86)}} path for Win32 build config| |libevent 2.1.10-stable|C:\libs\libevent-2.1.10-stable\include|from [github|https://github.com/libevent/libevent/releases/download/release-2.1.10-stable/libevent-2.1.10-stable.tar.gz]. I can't build the latest libevent (2.1.11-stable) - missing header errors. I managed to at least build 2.1.10 by running {{nmake -f Makefile.nmake}} in the libevent main folder. Which version should be used for Thrift?| # Build of libthrift in x64 (and Win32), but get compile errors: ||Code||Description||Project||File||Line|| |C1083|Cannot open source file: 'src\thrift\concurrency\BoostMonitor.cpp': No such file or directory|libthrift|C:\libs\copy\thrift-0.13.0\lib\cpp\c1xx|1| |C1083|Cannot open source file: 'src\thrift\concurrency\BoostMutex.cpp': No such file or directory|libthrift|C:\libs\copy\thrift-0.13.0\lib\cpp\c1xx|1| |C1083|Cannot open source file: 'src\thrift\concurrency\BoostThreadFactory.cpp': No such file or directory|libthrift|C:\libs\copy\thrift-0.13.0\lib\cpp\c1xx|1| |C1083|Cannot open source file: 'src\thrift\concurrency\StdThreadFactory.cpp': No such file or directory|libthrift|C:\libs\copy\thrift-0.13.0\lib\cpp\c1xx|1| |C1083|Cannot open source file: 'src\thrift\concurrency\Util.cpp': No such file or directory|libthrift|C:\libs\copy\thrift-0.13.0\lib\cpp\c1xx|1| |C1083|Cannot open include file: 'event2/event-config.h': No such file or directory|libthrift|C:\libs\libevent-2.1.10-stable\include\event.h|44| |C1083|Cannot open include file: 'thrift/config.h': No such file or directory|libthrift|C:\libs\copy\thrift-0.13.0\lib\cpp\src\thrift\transport\THttpClient.cpp|25| |C1083|Cannot open include file: 'thrift/config.h': No such file or directory|libthrift|C:\libs\copy\thrift-0.13.0\lib\cpp\src\thrift\transport\THttpServer.cpp|24| |C2491|'apache::thrift::transport::TSSLSocketFactory::manualOpenSSLInitialization_': definition of dllimport static data member not allowed|libthrift|C:\libs\copy\thrift-0.13.0\lib\cpp\src\thrift\transport\TSSLSocket.cpp|851| Why does the project reference nonexistent cpp files? After I removed them and added {{C:\libs\libevent-2.1.10-stable\WIN32-Code\nmake}} to the include paths, I still have bottom 3 errors that I don't know how to fix. In summary, it is a pain to build the C++ library for Thrift in Windows. When I raised this bug in my previous job, I had the .lib files directly as nuget package. I never had to build the library from source. > C++ clients crash when exceptions are typedefed in the IDL > ---------------------------------------------------------- > > Key: THRIFT-4781 > URL: https://issues.apache.org/jira/browse/THRIFT-4781 > Project: Thrift > Issue Type: Bug > Components: C++ - Compiler > Affects Versions: 0.11.0, 0.12.0 > Reporter: Andrej Nazarov > Priority: Major > > If exceptions are typedefed in the IDL, they're generated as pointers in Cpp. > This causes a runtime crash (memory access violation) on the C++ client-side > when a server sends that exception and the client tries to read it. Example > follows: > {code:java|title=service.thrift} > namespace * thrifttest.service > include "errors.thrift" > typedef errors.FooError FooError > service FooBarService > { > string getFooString(1: i32 stringLength) throws (1: FooError e); > string getBarString(1: i32 stringLength) throws (1: errors.BarError e); > } > {code} > {code:java|title=errors.thrift} > namespace * thrifttest.errors > exception FooError { > 1: string message > } > exception BarError { > 1: string message > } > {code} > {code:java|title=FooBarService.h} > class FooBarService_getFooString_presult { > public: > virtual ~FooBarService_getFooString_presult() throw(); > std::string* success; > FooError* e; //note pointer declaration of the exception field > // snip... > class FooBarService_getBarString_presult { > public: > virtual ~FooBarService_getBarString_presult() throw(); > std::string* success; > ::thrifttest::errors::BarError e; //note different declaration of the > exception field > //snip > {code} > {code:java|title=FooBarService.cpp} > uint32_t > FooBarService_getFooString_presult::read(::apache::thrift::protocol::TProtocol* > iprot) { > // snip... > while (true) > { > // snip... > switch (fid) > { > // snip... > case 1: > if (ftype == ::apache::thrift::protocol::T_STRUCT) { > xfer += (*(this->e)).read(iprot); // <-- this line causes access > violation crash because the pointer is not initialized > this->__isset.e = true; > // snip... > uint32_t > FooBarService_getBarString_presult::read(::apache::thrift::protocol::TProtocol* > iprot) { > // snip... > while (true) > { > // snip... > switch (fid) > { > // snip... > case 1: > if (ftype == ::apache::thrift::protocol::T_STRUCT) { > xfer += this->e.read(iprot); //<-- this gets read OK. > this->__isset.e = true; > //snip > {code} > This happens regardless of server language (reproducible if server throwing > the exceptions is Java, Python or C++) > I guess this logic in > [t_cpp_generator.cc:1104|https://github.com/apache/thrift/blob/0.11.0/compiler/cpp/src/thrift/generate/t_cpp_generator.cc#L1104] > gets deceived in case of typedefed exceptions: > {code:java|title=t_cpp_generator.cc} > (pointers && !(*m_iter)->get_type()->is_xception()), > {code} > I'm no Thrift compiler expert, but I assume there is a reason why you don't > want exceptions to be declared as pointers. Yet in this case they clearly are. -- This message was sent by Atlassian Jira (v8.3.4#803005)