我目前正在开发C ++库,并且正在使用cmake
作为构建系统。我不是cmake的新手,但是我可以对其进行设置,以便它成功找到外部库,并最终将我的库创建为共享库。
为了测试该库,我创建了一个非常小的测试程序(main.cc),该程序链接到该库。测试程序也可以成功编译,我可以运行该程序并使用我的库。
但是,当结束程序时,该程序在我的代码中对free
的某些调用中崩溃,并且valgrind
还显示了一些无效的空闲时间。我已经分析了问题,并且可以看到某些受影响的struct
包含垃圾,而不是正确初始化(零)。但是,代码与此不匹配,并且我找不到根本原因。
事实证明,当我不创建共享库而是直接使用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