В настоящее время я занимаюсь разработкой библиотеки C ++ и использую cmake
в качестве системы сборки. Я новичок в cmake, однако мне удалось настроить его так, чтобы он успешно находил внешние библиотеки и в итоге создавал мою библиотеку как разделяемую библиотеку.
Чтобы протестировать библиотеку, я создал очень минимальную тестовую программу (main.cc), которая связывается с библиотекой. Тестовая программа также успешно компилируется, и я могу запустить программу и использовать свою библиотеку.
Однако , когда программа завершается, в некоторых кодах происходит сбой при вызове free
в моем коде, и valgrind
также выявляет несколько недействительных освобождений. Я проанализировал проблему и вижу, что некоторые из затронутых struct
s содержат мусор, вместо того, чтобы инициализироваться должным образом (с нуля). Однако код не соответствует этому, и я не могу найти основную причину.
Оказывается, что когда я не создаю разделяемую библиотеку, а вместо этого создаю исполняемый файл напрямую с помощью cmake, все работает хорошо, и valgrind будет показывать ровно ноль ошибок.
Это мой CMakeLists.txt:
cmake_minimum_required(VERSION 2.8.9)
project(cex)
set(CMAKE_BUILD_TYPE Release)
set (CEX_VERSION_MAJOR 1)
set (CEX_VERSION_MINOR 0)
set (CEX_VERSION_PATCH 0)
# configure a header file to pass some of the CMake settings
# to the source code
configure_file (
"${PROJECT_SOURCE_DIR}/CexConfig.h.in"
"${PROJECT_SOURCE_DIR}/include/cex/cex_config.h"
)
# add more cmake rules (for libevent & libevhtp & libz)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
# Find mandatory libraries libevent + libevhtp
find_package(LibEvent REQUIRED)
list(APPEND LIBCEX_EXTERNAL_LIBS ${LIBEVENT_LIBRARIES})
list(APPEND package_deps LibEvent)
find_package(LibEvhtp REQUIRED)
list(APPEND LIBCEX_EXTERNAL_LIBS ${LIBEVHTP_LIBRARIES})
list(APPEND package_deps LibEvhtp)
# Find optional libraries openssl + zlib
if(NOT CEX_DISABLE_SSL)
find_package(OpenSSL)
if(OPENSSL_FOUND)
add_definitions(-DCEX_WITH_SSL)
list(APPEND LIBCEX_EXTERNAL_LIBS OpenSSL::SSL OpenSSL::Crypto)
list(APPEND package_deps OpenSSL)
endif()
endif()
if(NOT CEX_DISABLE_Z)
find_package(LibZ)
if(LIBZ_FOUND)
add_definitions(-DCEX_WITH_ZLIB)
list(APPEND LIBCEX_EXTERNAL_LIBS ${LIBZ_LIBRARIES})
list(APPEND package_deps LibZ)
endif()
endif()
# add project headers
include_directories(include)
include_directories(include/cex)
# add project sources
file(GLOB SOURCES "src/*.cc")
# generate the library
#add_library(cex SHARED ${SOURCES})
add_executable(cex ${SOURCES} "main.cc")
# compiler options & dependencies
target_compile_options(cex PRIVATE -std=c++11)
target_link_libraries(${PROJECT_NAME} ${OPENSSL_LIBRARIES})
target_link_libraries(cex PUBLIC ${LIBCEX_EXTERNAL_LIBS})
install(TARGETS cex DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)
install(DIRECTORY ${CMAKE_SOURCE_DIR}/include/ DESTINATION ${CMAKE_INSTALL_PREFIX}/include FILES_MATCHING PATTERN "*.h*")
И дерево моего проекта выглядит так:
+ build
| \
| + libcex.dylib
+ cmake // FindLibEvent, FindLibZ, FindLibEvhtp
+ include
| \
| + cex
| | \
| | + *hpp // all project headers
| + cex.hpp
+ src
| \
| *cc // all project source files
+ CMakeLists.txt
+ main.cc
При использовании разделяемой библиотеки я скомпилирую тестовую программу следующим образом:
clang -std=c++11 -I./include -I./include/cex main.cc -I/usr/local/ssl/include -L./build -lcex -L/usr/local/ssl/lib/ -lssl -lc++ -o serv
Вывод тестовой программы при использовании непосредственно скомпилированного исполняемого файла без библиотеки:
> ./cex
allocating empty config [NULL]
allocating empty config [NULL]
end of program, freeing now
--
free [NULL]
free [NULL]
free [NULL]
free [NULL]
free [NULL]
free [NULL]
free [NULL]
free [NULL]
--
free [NULL]
free [NULL]
free [NULL]
free [NULL]
free [NULL]
free [NULL]
free [NULL]
free [NULL]
Вывод при использовании тестовой программы + общая библиотека:
> ./cex
allocating empty config [NULL]
allocating empty config [NULL]
end of program, freeing now
--
free [NULL]
free [NULL]
free [NULL]
free [NULL]
free [NULL]
free [NULL]
free [NULL]
free [NULL]
--
free [UH��]����fD]
free [UH��SPH������H��H�[]�:�]
free [NULL]
free [�&��]
free [UH��]�6]
free [NULL]
free [UH��SPH���R���H��H�[]��}]
free [UH��]�6]
serv(1832,0x7fffad967340) malloc: *** error for object 0x10742d720: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Valgrind не будет никакой реальной помощи:
==450== Invalid free() / delete / delete[] / realloc()
==450== at 0x1000ABB6D: free (vg_replace_malloc.c:533)
==450== by 0x1000C48FB: cex::Server::Config::~Config() (in /Development/httpsrv/build/libcex.dylib)
==450== by 0x100000E7E: main (in ./cex)
==450== Address 0x1000c1720 is in the Text segment of /Development/httpsrv/build/libcex.dylib
==450== at 0x1000C1720: cex::Server::~Server() (in /Development/httpsrv/build/libcex.dylib)
==450==
==450== Invalid free() / delete / delete[] / realloc()
==450== at 0x1000ABB6D: free (vg_replace_malloc.c:533)
==450== by 0x1000C4908: cex::Server::Config::~Config() (in /Development/httpsrv/build/libcex.dylib)
==450== by 0x100000E7E: main (in ./cex)
==450== Address 0x1000c1730 is in the Text segment of /Development/httpsrv/build/libcex.dylib
==450== at 0x1000C1730: cex::Server::~Server() (in /Development/httpsrv/build/libcex.dylib)
==450==
==450== Invalid free() / delete / delete[] / realloc()
==450== at 0x1000ABB6D: free (vg_replace_malloc.c:533)
==450== by 0x1000C4922: cex::Server::Config::~Config() (in /Development/httpsrv/build/libcex.dylib)
==450== by 0x100000E7E: main (in ./cex)
==450== Address 0x100294a20 is in the Data segment of /Development/httpsrv/build/libcex.dylib
Вывод otool -L
выглядит правильно:
> otool -L cex
cex:
/Development/httpsrv/build/libcex.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.0.0)
Что может быть причиной этой проблемы / различия между прямым исполняемым файлом и разделяемой библиотекой? Я думаю, что я правильно связываю библиотеки, поэтому я не знаю, как может быть разница? : S