You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@thrift.apache.org by "Andrej Nazarov (Jira)" <ji...@apache.org> on 2020/04/17 22:25:00 UTC

[jira] [Comment Edited] (THRIFT-4781) C++ clients crash when exceptions are typedefed in the IDL

    [ https://issues.apache.org/jira/browse/THRIFT-4781?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17086110#comment-17086110 ] 

Andrej Nazarov edited comment on THRIFT-4781 at 4/17/20, 10:24 PM:
-------------------------------------------------------------------

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.


was (Author: andrejn):
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)