c++ Aws::Delete()正在尝试对指向零页的指针执行dynamic_cast

yizd12fk  于 2023-01-28  发布在  其他
关注(0)|答案(1)|浏览(115)

我正在使用AWS SDK for C++访问S3 bucket。这是一个更大的虚幻引擎项目的一部分。因此,AWS SDK正在使用Unreal Engine分配器,通过Aws::Utils::Memory::MemorySystemInterface连接。当我的某个请求超出范围时(并且被破坏),我在Aws::Delete()中得到了一个分段错误,这只发生在一个特定的GetObject请求中,我已经为该请求指定了一个流类型。
中断请求的代码如下所示:

Aws::S3::Model::GetObjectRequest request;
request.SetBucket(bucket);
request.SetKey(filename);
request.SetResponseStreamFactory([destination_file]() 
{return Aws::New<Aws::FStream>("getdata", destination_file, std::ios_base::out | std::ios_base::binary); }); 
//^ suspect this line to be causing problems, somehow.

Aws::S3::Model::GetObjectOutcome outcome = s3.GetObject(request);
if (!outcome.IsSuccess())
{
    Completed.Broadcast(fullpath, false);
    return;
}
else 
{
    fullpath = to_file;
    Completed.Broadcast(fullpath, true);
    return;
}
//request and outcome leave scope here, triggering an exception.

请求成功完成(outcome.IsSuccess()true),文件出现在正确的位置。一旦outcomerequest(我不确定是哪个)离开范围,它就会崩溃:

Exception thrown at 0x00007FFA0CC2612A (vcruntime140.dll) in UnrealEditor.exe: 
0xC0000005: Access violation reading location 0x0000000000000068.

使用以下调用堆栈:

vcruntime140.dll!00007ffa0cc2612a() Unknown
    [Inline Frame] aws-cpp-sdk-core.dll!Aws::Delete(std::basic_iostream<char,std::char_traits<char>> * pointerToT) Line 117 C++
    aws-cpp-sdk-core.dll!Aws::Utils::Stream::ResponseStream::ReleaseStream() Line 62    C++
    aws-cpp-sdk-core.dll!Aws::Utils::Stream::ResponseStream::~ResponseStream() Line 54  C++
    UnrealEditor-Plugin.dll!UPlugin::Activate() Line 56 C++

具体来说,异常在AwsMemory.h中触发:

template<typename T>
    typename std::enable_if<std::is_polymorphic<T>::value>::type Delete(T* pointerToT)
    {
        if (pointerToT == nullptr)
        {
            return;
        }
        // deal with deleting objects that implement multiple interfaces
        // see casting to pointer to void in http://en.cppreference.com/w/cpp/language/dynamic_cast
        // https://stackoverflow.com/questions/8123776/are-there-practical-uses-for-dynamic-casting-to-void-pointer
        // NOTE: on some compilers, calling the destructor before doing the dynamic_cast affects how calculation of
        // the address of the most derived class.
        void* mostDerivedT = dynamic_cast<void*>(pointerToT); // <-- exception
        pointerToT->~T();
        Free(mostDerivedT);
    }

ReleaseStream()ResponseStream()似乎只是Aws::Delete在这个特定示例中的 Package 器,唯一需要注意的是ReleaseStream在调用Delete之前刷新流。然而它是。这 * 应该 * 都发生在一个线程上。我还验证了所有相关的局部变量(如destination_file)都是有效的。
这个项目已经完成了其他请求(List,Put & Get)而没有问题,尽管它们都没有指定流工厂。

wvt8vs2t

wvt8vs2t1#

UE4是在没有RTTI的情况下编译的,所以(很明显)dynamic_cast不起作用。我相信这就是问题所在。在多态类型上调用Delete而不使用dynamic_cast<void*>技巧有一个新问题。

相关问题