为什么用POCO_ENABLE_CPP11编译POCO会导致构造函数的无效内存写入?

时间:2019-05-19 22:27:54

标签: poco poco-libraries

当我使用Clang或GCC在Ubuntu Bionic上编译POCO时,我得到无效的写入(导致崩溃和valgrind的错误报告)。设置-DDISABLE_CPP11 = ON -DDISABLE_CPP14 = ON可解决此问题。

该错误易于重现:只需使用'new'分配Poco :: JSON:Object,然后立即将其删除。 Presto:记忆重重。

我没有深入研究,但是我怀疑它与仅在c11或更高版本中实现的新对齐功能有关。 sizeof(Poco :: JSON :: Object)的结果保持不变,其他POCO类也未显示该问题,因此我猜测Poco :: JSON :: Object的某些成员在以某种方式构造时会对齐会覆盖已分配的边界,这似乎不太可能,但似乎是所报告的-始终覆盖1到8个字节。

另外,检查为JSON / Object.cpp生成的.o文件,发现该文件大约大50%。

这是一个已知问题吗?而且我的应用程序编译错误吗?例如,构建主可执行文件时是否需要显式设置ENABLE_CPP11?

我现在暂时禁用CPP11和CPP14,但是由于这不是默认设置,因此感觉像是一种解决方法。

...

对于那些在家中跟随的人:

git clone -b poco-1.9.1 https://github.com/pocoproject/poco
cd poco
cmake .
make -j4 VERBOSE=1
make install

产生:

[ 42%] Building CXX object JSON/CMakeFiles/JSON.dir/src/Object.cpp.o
cd /app/poco/JSON && /usr/bin/c++  -DJSON_EXPORTS -DPOCO_ENABLE_CPP11 -DPOCO_ENABLE_CPP14 -DPOCO_HAVE_FD_EPOLL -DPOCO_OS_FAMILY_UNIX -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -D_REENTRANT -D_THREAD_SAFE -D_XOPEN_SOURCE=500 -I/app/poco/JSON/include -I/app/poco/JSON/src -I/app/poco/Foundation/include  -O2 -g -DNDEBUG -fPIC   -std=gnu++14 -o CMakeFiles/JSON.dir/src/Object.cpp.o -c /app/poco/JSON/src/Object.cpp

而且,要再现该错误:

#include <Poco/JSON/Object.h>

int main ( int argc, char** argv ) {
    Poco::JSON::Object* object = new Poco::JSON::Object ();
    delete object;
}

一个用于构建它的Cmake文件:

cmake_minimum_required ( VERSION 3.10.2 )
project ( volition )

set ( CMAKE_CXX_STANDARD 14 )

add_executable ( volition src/volition/main-memtest.cpp )

target_link_libraries ( volition
    PocoJSON
    PocoFoundation
    ${CMAKE_DL_LIBS}
)

install ( TARGETS volition DESTINATION bin )

构建时的详细输出:

[ 50%] Building CXX object CMakeFiles/volition.dir/src/volition/main-memtest.cpp.o
/usr/bin/c++    -std=gnu++14 -o CMakeFiles/volition.dir/src/volition/main-memtest.cpp.o -c /app/src/volition/main-memtest.cpp

来自Valgrind:

==1== Invalid write of size 8
==1==    at 0x4E66D28: SharedPtr (SharedPtr.h:118)
==1==    by 0x4E66D28: Poco::JSON::Object::Object(int) (Object.cpp:30)
==1==    by 0x108A35: main (in /usr/local/bin/volition)
==1==  Address 0x6808eb8 is 0 bytes after a block of size 168 alloc'd
==1==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1==    by 0x108A25: main (in /usr/local/bin/volition)
==1== 
==1== Invalid write of size 1
==1==    at 0x4E66D33: Poco::JSON::Object::Object(int) (Object.cpp:30)
==1==    by 0x108A35: main (in /usr/local/bin/volition)
==1==  Address 0x6808ec0 is 8 bytes after a block of size 168 alloc'd
==1==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1==    by 0x108A25: main (in /usr/local/bin/volition)
==1== 
==1== Invalid read of size 8
==1==    at 0x4E66AD4: release (SharedPtr.h:417)
==1==    by 0x4E66AD4: ~SharedPtr (SharedPtr.h:148)
==1==    by 0x4E66AD4: Poco::JSON::Object::~Object() (Object.cpp:79)
==1==    by 0x4E66C08: Poco::JSON::Object::~Object() (Object.cpp:81)
==1==    by 0x108A57: main (in /usr/local/bin/volition)
==1==  Address 0x6808eb8 is 0 bytes after a block of size 168 alloc'd
==1==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1==    by 0x108A25: main (in /usr/local/bin/volition)
==1== 
==1== Invalid write of size 8
==1==    at 0x4E66B21: release (SharedPtr.h:418)
==1==    by 0x4E66B21: ~SharedPtr (SharedPtr.h:148)
==1==    by 0x4E66B21: Poco::JSON::Object::~Object() (Object.cpp:79)
==1==    by 0x4E66C08: Poco::JSON::Object::~Object() (Object.cpp:81)
==1==    by 0x108A57: main (in /usr/local/bin/volition)
==1==  Address 0x6808eb8 is 0 bytes after a block of size 168 alloc'd
==1==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1==    by 0x108A25: main (in /usr/local/bin/volition)

tom脚sto脚。

0 个答案:

没有答案