Почему компиляция POCO с POCO_ENABLE_CPP11 вызывает недопустимые записи в память из конструкторов? - PullRequest
0 голосов
/ 20 мая 2019

Когда я компилирую POCO в Ubuntu Bionic с помощью Clang или GCC, я получаю недопустимые записи (что приводит к сбоям и сообщениям об ошибках из valgrind). Установка -DDISABLE_CPP11 = ON -DDISABLE_CPP14 = ON решает проблему.

Ошибка легко воспроизводится: просто выделите Poco :: JSON: Object с помощью 'new', а затем немедленно удалите его. Presto: топот памяти.

Я не посмотрел глубоко, но подозреваю, что это как-то связано с новой функцией выравнивания, которая реализована только для c11 или новее. Результат sizeof (Poco :: JSON :: Object) не изменяется, и другие классы POCO не обнаруживают проблему, поэтому я предполагаю, что некоторые члены Poco :: JSON :: Object выравниваются при построении таким образом это перезаписывает выделенную границу, что кажется невероятным, но представляется тем, о чем сообщается - последовательно перезаписываются от 1 до 8 байтов.

Кроме того, проверка файла .o, созданного для JSON / Object.cpp, показала, что он примерно на 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

А из Вальгринда:

==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)

топать топать топать.

...