Description
Describe the bug
ClientWithAsyncTemplateMethods
has the following constructor:
The static_cast<AwsServiceClientT*>(this)
is meant to cast the base this
pointer to the corresponding derived this
pointer (which can have a different address when multiple inheritance is involved).
The problem, though, is that it happens in the base class constructor, so the derived object is not yet constructed yet. And, therefore, the static_cast
to the derived this
is undefined behavior.
This is flagged by some of the UBSan builds in Apache Arrow:
apache/arrow#46863
Start test: S3FileSystem
/var/folders/x7/ch5v91h56_zbvbd1y2f600dm0000gn/T/RtmpjRMkwO/file8951246f6d2e/_deps/aws-sdk-cpp-src/src/aws-cpp-sdk-core/include/aws/core/client/AWSClientAsyncCRTP.h:51:40: runtime error: downcast of address 0x61b00011cd98 which does not point to an object of type 'Aws::S3::S3Client'
0x61b00011cd98: note: object is of type 'Aws::Client::AWSXMLClient'
00 00 00 00 b0 eb b9 28 01 00 00 00 75 73 2d 65 61 73 74 2d 31 00 e6 8b 01 00 00 00 00 00 00 00
^~~~~~~~~~~~~~~~~~~~~~~
vptr for 'Aws::Client::AWSXMLClient'
#0 0x0001245e7770 in Aws::Client::ClientWithAsyncTemplateMethods<Aws::S3::S3Client>::ClientWithAsyncTemplateMethods()+0x1f0 (arrow.so:arm64+0x701f770)
#1 0x0001245ebe10 in Aws::S3::S3Client::S3Client(std::__1::shared_ptr<Aws::Auth::AWSCredentialsProvider> const&, std::__1::shared_ptr<Aws::Endpoint::EndpointProviderBase<Aws::S3::S3ClientConfiguration, Aws::S3::Endpoint::S3BuiltInParameters, Aws::S3::Endpoint::S3ClientContextParameters>>, Aws::S3::S3ClientConfiguration const&)+0x310 (arrow.so:arm64+0x7023e10)
Regression Issue
- Select this option if this issue appears to be a regression.
Expected Behavior
Undefined behavior should not occur when constructing S3Client.
Current Behavior
Undefined behavior is detected when constructing S3Client. See detailed messages above.
Reproduction Steps
The Apache Arrow CI job is too complicated to describe here, sorry.
Possible Solution
A possible solution would be to pass the derived pointer explicitly to the ClientWithAsyncTemplateMethods
constructor, so that no static_cast
is required.
ClientWithAsyncTemplateMethods(AwsServiceClientT* derived)
: m_isInitialized(true),
m_operationsProcessed(0)
{
Aws::Utils::ComponentRegistry::RegisterComponent(AwsServiceClientT::GetServiceName(),
derived,
&AwsServiceClientT::ShutdownSdkClient);
}
Additional Information/Context
No response
AWS CPP SDK version used
1.11.594