MacOS上的cmake +共享库问题

时间:2018-06-28 11:46:06

标签: c++ macos cmake shared-libraries

我目前正在开发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

0 个答案:

没有答案