Skip to content

s3Client "basic_string::_M_construct" error during runtime #748

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
DannyMoss opened this issue Dec 6, 2017 · 8 comments
Closed

s3Client "basic_string::_M_construct" error during runtime #748

DannyMoss opened this issue Dec 6, 2017 · 8 comments
Labels
help wanted We are asking the community to submit a PR to resolve this issue.

Comments

@DannyMoss
Copy link

DannyMoss commented Dec 6, 2017

What platform/OS are you using?

Windows 7 , 64bit

What compiler are you using? what version?

mingw64_7.2.0_seh
gcc version 7.2.0 (x86_64-posix-seh-rev1, Built by MinGW-W64 project)

What's your CMake arguments?

cmake -G "MinGW Makefiles" -DTARGET_ARCH="WINDOWS" -DENABLE_TESTING="OFF" -DBUILD_ONLY="s3" -DCMAKE_CXX_FLAGS="-Wa,-mbig-obj" -DCURL_LIBRARY="c:\aws_sdk\curl-7.57.0-win64-mingw\lib\libcurl.dll.a" -DCURL_INCLUDE_PATH="c:\aws_sdk\curl-7.57.0-win64-mingw\include\curl" -DCURL_INCLUDE_DIR="c:\aws_sdk\curl-7.57.0-win64-mingw\include" -DCMAKE_BUILD_TYPE=Release C:/aws_sdk/aws-sdk-cpp-master/

Other libs:

Curl: 7.57.0-win64
OpenSSL: 1.1.0g

  1. I have to use only S3 client (upload files into S3 storage).

  2. I've managed to build S3 client, (it didn't make tests) it produced:
    libaws-cpp-sdk-core.dll
    libaws-cpp-sdk-core.dll.a
    libaws-cpp-sdk-s3.dll
    libaws-cpp-sdk-s3.dll.a

  3. I was able to make a test project using QT 5.9 framework, compile it and link (using same compiler) against these libs and dll's

  4. I'm calling: Aws::InitAPI(options);

  5. program works fine till first attempt to create S3 client instance:
    Aws::S3::S3Client s3_client(clientConfig);
    then I have an error:

terminate called after throwing an instance of 'std::logic_error'
what():  basic_string::_M_construct null not valid
This application has requested the Runtime to terminate it in an unusual way. Please contact the
application's support team for more information.

Any idea - why? I had to change few things in AWS sources (mostly from #45 ) to make it compilable by MinGW64. Is it blind alley?
Should I try to build S3 client in debug mode (or even static) and look for reasons or just forget about MinGW-W64?

Any help appreciated!
Cheers!

@DannyMoss DannyMoss changed the title s3 Client runtime error s3 Client " basic_string::_M_construct" error during runtime Dec 6, 2017
@DannyMoss DannyMoss changed the title s3 Client " basic_string::_M_construct" error during runtime s3Client "basic_string::_M_construct" error during runtime Dec 6, 2017
@singku
Copy link
Contributor

singku commented Dec 6, 2017

Code snippet?

@DannyMoss
Copy link
Author

DannyMoss commented Dec 7, 2017

Sure - here is whole code: (based on [copy-paste] that example: https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/cpp/example_code/s3/list_objects.cpp )

#include <aws/core/Aws.h>
#include <aws/s3/S3Client.h>
#include <aws/s3/model/PutObjectRequest.h>
#include <iostream>
#include <fstream>


int main()
{
    std::cout << "AWS test !" << std::endl;

    Aws::SDKOptions options;
       Aws::InitAPI(options);
       {
           const Aws::String bucket_name = "my_bucket";
           const Aws::String key_name = "my_key";
           const Aws::String file_name = "filepath_to_upload";
           const Aws::String region("");

           std::cout << "Uploading " << file_name << " to S3 bucket " <<
               bucket_name << " at key " << key_name << std::endl;

           Aws::Client::ClientConfiguration clientConfig;
           if (!region.empty())
               clientConfig.region = region;
               Aws::S3::S3Client s3_client(clientConfig);//-- **here is a problem**  --

                   Aws::S3::Model::PutObjectRequest object_request;
                   object_request.WithBucket(bucket_name).WithKey(key_name);

                   // Binary files must also have the std::ios_base::bin flag or'ed in
                   auto input_data = Aws::MakeShared<Aws::FStream>("PutObjectInputStream",
                       file_name.c_str(), std::ios_base::in | std::ios_base::binary);

                   object_request.SetBody(input_data);

                   auto put_object_outcome = s3_client.PutObject(object_request);

                   if (put_object_outcome.IsSuccess())
                   {
                       std::cout << "Done!" << std::endl;
                   }
                   else
                   {
                       std::cout << "PutObject error: " <<
                           put_object_outcome.GetError().GetExceptionName() << " " <<
                           put_object_outcome.GetError().GetMessage() << std::endl;
                   }
       }
       Aws::ShutdownAPI(options);
    std::cout << "AWS done!" << std::endl;
    return 0;
}

@DannyMoss
Copy link
Author

And just in case - results of configure: (this time debug)

C:\aws_sdk\bin64>cmake -G "MinGW Makefiles" -DTARGET_ARCH="WINDOWS" -DENABLE_TES
TING="OFF" -DBUILD_ONLY="s3" -DCMAKE_CXX_FLAGS="-Wa,-mbig-obj" -DCURL_LIBRARY="c
:\aws_sdk\curl-7.57.0-win64-mingw\lib\libcurl.dll.a" -DCURL_INCLUDE_PATH="c:\aws
_sdk\curl-7.57.0-win64-mingw\include\curl" -DCURL_INCLUDE_DIR="c:\aws_sdk\curl-7
.57.0-win64-mingw\include" -DCMAKE_BUILD_TYPE=Debug C:/aws_sdk/aws-sdk-cpp-maste
r/
-- Could NOT find Git (missing: GIT_EXECUTABLE)
-- Building AWS libraries as shared objects
-- Generating windows build config
-- Building project version: 1.3.11
-- The CXX compiler identification is GNU 7.2.0
-- Check for working CXX compiler: C:/mingw/mingw64_7.2.0_seh/mingw64/bin/g++.ex
e
-- Check for working CXX compiler: C:/mingw/mingw64_7.2.0_seh/mingw64/bin/g++.ex
e -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Encryption: Bcrypt
-- Http client: Curl
-- Found CURL: C:/aws_sdk/curl-7.57.0-win64-mingw/lib/libcurl.dll.a (found versi
on "7.57.0")
--   Curl include directory: C:/aws_sdk/curl-7.57.0-win64-mingw/include
--   Curl library: C:/aws_sdk/curl-7.57.0-win64-mingw/lib/libcurl.dll.a
-- Considering s3
-- The C compiler identification is GNU 7.2.0
-- Check for working C compiler: C:/mingw/mingw64_7.2.0_seh/mingw64/bin/gcc.exe
-- Check for working C compiler: C:/mingw/mingw64_7.2.0_seh/mingw64/bin/gcc.exe
-- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Updating version info to 1.3.11
-- Custom memory management enabled; stl objects now using custom allocators
-- Configuring done
-- Generating done

@DannyMoss
Copy link
Author

DannyMoss commented Dec 7, 2017

Ok, I think I found the issue:
I've build debug and started looking for error. It was change proposed at #45 :
Aws::String result = std::getenv(variableName)
inside of:

Aws::String GetEnv(const char *variableName)
{

inside of the file:
aws-sdk-cpp-master\aws-cpp-sdk-core\source\platform\windows\Environment.cpp
It worked well at the first call for env variable named: "USERPROFILE" but during second call for env variable: "AWS_SHARED_CREDENTIALS_FILE" - it was causing runtime error in file:
basic_string.h line 166: return std::pointer_traits<pointer>::pointer_to(*_M_local_buf);

I've changed std::getenv to GetEnvironmentVariable(...) and problem went away...
std::getenv() is marked as deprecated in MinGW-W64
_dupenv_s() canot be distributed with MinGW due to some (licensing?) reasons

GetEnvironmentVariable needs some temporary buffer and I did it in some ugly way, but it doesn't crash any longer. If it will be worth - I'll provide code snippet.
Update:
Just tested on release - works fine.

@Bu11etmagnet
Copy link

The problem is that the code is passing a null pointer to the std::string constructor. The return value of getenv should be checked for nullptr before constructing a std::string from it.
GetEnvironmentVariable is somewhat better designed because it has a return value that is separate from the returned string. Unfortunately, it's Windows-only. Besides, it's unnecessary to use it. Once the usage of getenv is fixed, it would work on all platforms.

@DannyMoss
Copy link
Author

DannyMoss commented Dec 7, 2017

You are very right, indeed! (Shame - I was blind or too tired - 3am)

Aws::String result;
       char* value = std::getenv(variableName);
       if(value!=NULL) result = value;

will solve an issue.
But std::getenv is still marked as deprecated and may cause warnings.

Unfortunately, it's Windows-only

BTW - whole file "aws-cpp-sdk-core\source\platform\windows\Environment.cpp" is windows only :)

@Bu11etmagnet
Copy link

This is what aws-cpp-sdk-core/source/platform/linux-shared/Environment.cpp does:

Aws::String GetEnv(const char* variableName)
{
    auto variableValue = std::getenv(variableName);
    return Aws::String( variableValue ? variableValue : "" );
}

@JasonYuchen
Copy link

JasonYuchen commented May 8, 2018

@DannyMoss I followed your advice and successfully generate the libaws-cpp-sdk-core.a and libaws-cpp-sdk-s3.a. But when I linked a small test, I got a lot of undefined references:

g++ -std=c++11 -o main.exe main.cpp -laws-cpp-sdk-s3 -laws-cpp-sdk-core -lcurl
C:/msys64/usr/local/lib/../lib/libaws-cpp-sdk-core.a(FileSystem.cpp.obj):FileSystem.cpp:(.text+0xa90): undefined reference to `__imp_GetUserProfileDirectoryW'
C:/msys64/usr/local/lib/../lib/libaws-cpp-sdk-core.a(OSVersionInfo.cpp.obj):OSVersionInfo.cpp:(.text+0x226): undefined reference to `GetFileVersionInfoSizeA'
C:/msys64/usr/local/lib/../lib/libaws-cpp-sdk-core.a(OSVersionInfo.cpp.obj):OSVersionInfo.cpp:(.text+0x253): undefined reference to `GetFileVersionInfoA'
C:/msys64/usr/local/lib/../lib/libaws-cpp-sdk-core.a(OSVersionInfo.cpp.obj):OSVersionInfo.cpp:(.text+0x668): undefined reference to `VerQueryValueA'
C:/msys64/usr/local/lib/../lib/libaws-cpp-sdk-core.a(OSVersionInfo.cpp.obj):OSVersionInfo.cpp:(.text+0xaac): undefined reference to `VerQueryValueA'
C:/msys64/usr/local/lib/../lib/libaws-cpp-sdk-core.a(CryptoImpl.cpp.obj):CryptoImpl.cpp:(.text+0xee): undefined reference to `BCryptCloseAlgorithmProvider'
C:/msys64/usr/local/lib/../lib/libaws-cpp-sdk-core.a(CryptoImpl.cpp.obj):CryptoImpl.cpp:(.text+0x122): undefined reference to `BCryptDestroyKey'
......a lot similar error
C:/msys64/usr/local/lib/../lib/libaws-cpp-sdk-core.a(CryptoImpl.cpp.obj):CryptoImpl.cpp:(.text$_ZN3Aws5Utils6Crypto16Sha256BcryptImplD0Ev[_ZN3Aws5Utils6Crypto16Sha256BcryptImplD0Ev]+0x3a): undefined reference to `BCryptCloseAlgorithmProvider'
C:/msys64/usr/local/lib/../lib/libaws-cpp-sdk-core.a(CryptoImpl.cpp.obj):CryptoImpl.cpp:(.text$_ZN3Aws5Utils6Crypto20Sha256HMACBcryptImplD0Ev[_ZN3Aws5Utils6Crypto20Sha256HMACBcryptImplD0Ev]+0x3a): undefined reference to `BCryptCloseAlgorithmProvider'
collect2.exe: error: ld returned 1 exit status

Can you tell me how to fix this?
Thank you!

@justnance justnance added help wanted We are asking the community to submit a PR to resolve this issue. and removed help wanted labels Apr 19, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted We are asking the community to submit a PR to resolve this issue.
Projects
None yet
Development

No branches or pull requests

5 participants