【问题标题】:CMake Debug Symbols MissingCMake 调试符号丢失
【发布时间】:2015-12-23 17:23:12
【问题描述】:

我最近开始使用 CMake,但无法弄清楚如何让我的调试符号为 Valgrind 工作。所以,我做了一个测试项目来证明我的问题。如果没有 CMake,我只会用 -g 编译:

g++ -std=c++11 -g main.cpp -o test

我得到了我想要的test.dSYM 目录。根据How do you set GDB debug flag with cmake?,要获得 -g 标志,我应该使用参数

-D CMAKE_BUILD_TYPE=Debug

所以这就是我尝试过的。在名为Testing 的文件夹中,我创建了一个测试文件main.cpp,其内容如下:

#include <iostream>
using std::cout;

int main( int argc , const char* argv[] ) {
    int* leak = new int;
    int arr[] = { 1 , 2 , 3 , 4 };
    for ( int i : arr ) {
        cout << i << "\n";      
    }
    return 0;
}

Testing内部,我还创建了一个文件CMakeLists.txt,内容如下:

cmake_minimum_required( VERSION 3.1 )
project( Testing )
add_executable( test1 main.cpp )
set_property(TARGET test1 PROPERTY CXX_STANDARD 11)
set_property(TARGET test1 PROPERTY CXX_STANDARD_REQUIRED ON)

然后我创建了一个新目录Testing/cmake_build,并在该目录中运行了以下命令:

Testing/cmake_build$ cmake -D CMAKE_BUILD_TYPE=Debug ..
Testing/cmake_build$ make
Testing/cmake_build$ valgrind --leak-check=yes ./test

Valgrind 抱怨缺少 dSYM 目录。我自己找了一圈,没找到。因此,我没有在泄漏检查输出中获得行号,也无法调试我的项目:

==2388== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==2388== Command: ./test
==2388== 
--2388-- ./test:
--2388-- dSYM directory is missing; consider using --dsymutil=yes
1
2
3
4
==2388== 
==2388== HEAP SUMMARY:
==2388==     in use at exit: 29,443 bytes in 378 blocks
==2388==   total heap usage: 472 allocs, 94 frees, 36,027 bytes allocated
==2388== 
==2388== 4 bytes in 1 blocks are definitely lost in loss record 1 of 76
==2388==    at 0x47F1: malloc (vg_replace_malloc.c:300)
==2388==    by 0x4928D: operator new(unsigned long) (in /usr/lib/libc++.1.dylib)
==2388==    by 0x1000012E5: main (in ./test)
==2388== 
==2388== LEAK SUMMARY:
==2388==    definitely lost: 4 bytes in 1 blocks
==2388==    indirectly lost: 0 bytes in 0 blocks
==2388==      possibly lost: 0 bytes in 0 blocks
==2388==    still reachable: 4,096 bytes in 1 blocks
==2388==         suppressed: 25,343 bytes in 376 blocks
==2388== Reachable blocks (those to which a pointer was found) are not shown.
==2388== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==2388== 

应该说

==2530==    by 0x1000012E5: main (main.cpp:5)

谁能告诉我如何使用 CMake 来获取 dSYM 目录?谢谢。

编辑 1(制作所有命令):

这是在我的 makefile 中生成的 make all 命令:

all: cmake_check_build_system
    $(CMAKE_COMMAND) -E cmake_progress_start <Path>/Testing/cmake_build/CMakeFiles <Path>/Testing/cmake_build/CMakeFiles/progress.marks
    $(MAKE) -f CMakeFiles/Makefile2 all
    $(CMAKE_COMMAND) -E cmake_progress_start <Path>/Testing/cmake_build/CMakeFiles 0

编辑2(Makefile2的所有命令):

# Target rules for target CMakeFiles/test1.dir

# All Build rule for target.
CMakeFiles/test1.dir/all:
    $(MAKE) -f CMakeFiles/test1.dir/build.make CMakeFiles/test1.dir/depend
    $(MAKE) -f CMakeFiles/test1.dir/build.make CMakeFiles/test1.dir/build
    @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --progress-dir=<Path>/Testing/cmake_build/CMakeFiles --progress-num=1,2 "Built target test1"
.PHONY : CMakeFiles/test1.dir/all

# Include target in all.
all: CMakeFiles/test1.dir/all

编辑3(CmakeFiles/test1.dir/build.make):

# CMAKE generated file: DO NOT EDIT!
# Generated by "Unix Makefiles" Generator, CMake Version 3.4

# Delete rule output on recipe failure.
.DELETE_ON_ERROR:


#=============================================================================
# Special targets provided by cmake.

# Disable implicit rules so canonical targets will work.
.SUFFIXES:


# Remove some rules from gmake that .SUFFIXES does not remove.
SUFFIXES =

.SUFFIXES: .hpux_make_needs_suffix_list


# Suppress display of executed commands.
$(VERBOSE).SILENT:


# A target that is always out of date.
cmake_force:

.PHONY : cmake_force

#=============================================================================
# Set environment variables for the build.

# The shell in which to execute make rules.
SHELL = /bin/sh

# The CMake executable.
CMAKE_COMMAND = /usr/local/bin/cmake

# The command to remove a file.
RM = /usr/local/bin/cmake -E remove -f

# Escaping for special characters.
EQUALS = =

# The top-level source directory on which CMake was run.
CMAKE_SOURCE_DIR = <Path>/Desktop/Testing

# The top-level build directory on which CMake was run.
CMAKE_BINARY_DIR = <Path>/Desktop/Testing/cmake_build

# Include any dependencies generated for this target.
include CMakeFiles/test1.dir/depend.make

# Include the progress variables for this target.
include CMakeFiles/test1.dir/progress.make

# Include the compile flags for this target's objects.
include CMakeFiles/test1.dir/flags.make

CMakeFiles/test1.dir/main.cpp.o: CMakeFiles/test1.dir/flags.make
CMakeFiles/test1.dir/main.cpp.o: ../main.cpp
    @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=<Path>/Desktop/Testing/cmake_build/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/test1.dir/main.cpp.o"
    /Applications/Xcode6-Beta5.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++   $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o CMakeFiles/test1.dir/main.cpp.o -c <Path>/Desktop/Testing/main.cpp

CMakeFiles/test1.dir/main.cpp.i: cmake_force
    @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/test1.dir/main.cpp.i"
    /Applications/Xcode6-Beta5.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++  $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E <Path>/Desktop/Testing/main.cpp > CMakeFiles/test1.dir/main.cpp.i

CMakeFiles/test1.dir/main.cpp.s: cmake_force
    @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/test1.dir/main.cpp.s"
    /Applications/Xcode6-Beta5.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++  $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S <Path>/Desktop/Testing/main.cpp -o CMakeFiles/test1.dir/main.cpp.s

CMakeFiles/test1.dir/main.cpp.o.requires:

.PHONY : CMakeFiles/test1.dir/main.cpp.o.requires

CMakeFiles/test1.dir/main.cpp.o.provides: CMakeFiles/test1.dir/main.cpp.o.requires
    $(MAKE) -f CMakeFiles/test1.dir/build.make CMakeFiles/test1.dir/main.cpp.o.provides.build
.PHONY : CMakeFiles/test1.dir/main.cpp.o.provides

CMakeFiles/test1.dir/main.cpp.o.provides.build: CMakeFiles/test1.dir/main.cpp.o


# Object files for target test1
test1_OBJECTS = \
"CMakeFiles/test1.dir/main.cpp.o"

# External object files for target test1
test1_EXTERNAL_OBJECTS =

test1: CMakeFiles/test1.dir/main.cpp.o
test1: CMakeFiles/test1.dir/build.make
test1: CMakeFiles/test1.dir/link.txt
    @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --bold --progress-dir=<Path>/Desktop/Testing/cmake_build/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable test1"
    $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/test1.dir/link.txt --verbose=$(VERBOSE)

# Rule to build all files generated by this target.
CMakeFiles/test1.dir/build: test1

.PHONY : CMakeFiles/test1.dir/build

CMakeFiles/test1.dir/requires: CMakeFiles/test1.dir/main.cpp.o.requires

.PHONY : CMakeFiles/test1.dir/requires

CMakeFiles/test1.dir/clean:
    $(CMAKE_COMMAND) -P CMakeFiles/test1.dir/cmake_clean.cmake
.PHONY : CMakeFiles/test1.dir/clean

CMakeFiles/test1.dir/depend:
    cd <Path>/Desktop/Testing/cmake_build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" <Path>/Desktop/Testing <Path>/Desktop/Testing <Path>/Desktop/Testing/cmake_build <Path>/Desktop/Testing/cmake_build <Path>/Desktop/Testing/cmake_build/CMakeFiles/test1.dir/DependInfo.cmake --color=$(COLOR)
.PHONY : CMakeFiles/test1.dir/depend

编辑 4(进行详细输出):

/usr/local/bin/cmake -H<Path>/Desktop/Testing -B<Path>/Desktop/Testing/cmake_build --check-build-system CMakeFiles/Makefile.cmake 0
/usr/local/bin/cmake -E cmake_progress_start <Path>/Desktop/Testing/cmake_build/CMakeFiles <Path>/Desktop/Testing/cmake_build/CMakeFiles/progress.marks
/Applications/Xcode6-Beta5.app/Contents/Developer/usr/bin/make -f CMakeFiles/Makefile2 all
/Applications/Xcode6-Beta5.app/Contents/Developer/usr/bin/make -f CMakeFiles/test1.dir/build.make CMakeFiles/test1.dir/depend
cd <Path>/Desktop/Testing/cmake_build && /usr/local/bin/cmake -E cmake_depends "Unix Makefiles" <Path>/Desktop/Testing <Path>/Desktop/Testing <Path>/Desktop/Testing/cmake_build <Path>/Desktop/Testing/cmake_build <Path>/Desktop/Testing/cmake_build/CMakeFiles/test1.dir/DependInfo.cmake --color=
/Applications/Xcode6-Beta5.app/Contents/Developer/usr/bin/make -f CMakeFiles/test1.dir/build.make CMakeFiles/test1.dir/build

【问题讨论】:

  • 我想知道是不是 -D 和 CMAKE_BUILD_TYPE 之间的空格破坏了它。
  • @SergeyA 我试过-DCMAKE_BUILD_TYPE=Debug,不幸的是它产生了相同的结果。我还将可执行文件从 test 重命名为 test1,因为我错过了一条警告说 test 已保留。
  • 您是否查看了是否生成了正确的 make 文件?里面有 -g 吗?
  • 请注意 CXX_STANDARD_REQUIRED 属性已在 CMake 3.1 中引入,因此我建议您调整您的 cmake_minimum_required 版本。
  • @SergeyA 我在生成的 make all 命令中进行了编辑。它有几个变量并引用其他文件。如果您有兴趣查看任何特定文件,能否告诉我?

标签: c++ cmake


【解决方案1】:

尝试通过添加显式设置调试配置的 -g 标志
set(CMAKE_CXX_FLAGS_DEBUG "-g") 到您的 CMakeLists.txt,然后使用
-DCMAKE_BUILD_TYPE=Debug

重新运行 cmake

【讨论】:

  • 我试过这个,但很遗憾,它不起作用。 .dSYM 目录仍然不存在。
  • 您是否尝试过使用 --dsymutil=yes 选项运行 Valgrind?我对 osx 的构建系统了解不多,但根据 Valgrind's manual 的说法,该选项应该会导致运行 dsymutil 以生成 .dSYM 目录。这并不能解决从 cmake 生成 .dSYM 目录的更大问题,但似乎它至少应该让 Valgrind 工作
  • 要尝试的另一件事:根据我对事物的基本理解,.dSYM 目录包含 xcode 项目的调试信息。 GCC 实际上并没有创建 .dSYM 目录,它是由名为 dsymutil 的应用程序使用 gcc 提供的调试符号创建的,稍后在您的 makefile 中调用。使用 cmake,您可以使用 -G 选项指定正在生成的 makefile 的类型,因此可能像 cmake -G Xcode -D CMAKE_BUILD_TYPE=Debug .. 这样的东西会在生成的 makefile 中包含 dsymutil 步骤。
【解决方案2】:
  1. valgrind + leak-check - 推荐使用 AFAIK 调试版本
  2. 现在我会使用编译器选项地址清理程序而不是 valgrindleak-check。清理更快、更可靠(valgrind 有一些技术限制,因此无法找到所有内存问题)。
  3. 请注意,在cmake 项目中有4 default configurationsDebugReleaseRelWithDebInfoMinSizeRel。使用RelWithDebInfo 的配置创建带有符号文件的发布版本(我试图找出这种配置是否存在一些缺点,这就是我遇到这个 SO 问题的原因)。所以很可能你应该像这样构建你的项目:
cd build_dir
cmake .. -G <YOUR GENERATOR> <other config options>
cmake --build . --config RelWithDebInfo

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-29
    • 1970-01-01
    • 1970-01-01
    • 2012-02-29
    • 1970-01-01
    相关资源
    最近更新 更多