Ubuntu 系统下使用 GDB 调试需要进行一些提前的设置。
1. 安装 gdb
有些版本的系统可能没有安装该工具,需要自行安装。
cv@cv:~# sudo apt install gdb
2. 设置 ulimit 参数
ulimit 是Linux系统的内置功能,用于为由它生成的 Shell 进程及其子进程的资源的使用设置限制。
ulimit -a 用于显示当前所有的 limit 信息。
cv@cv:~# ulimit -a core file size (blocks, -c) unlimited data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 515120 max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 1048576 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) unlimited virtual memory (kbytes, -v) unlimited file locks (-x) unlimited在 Ubuntu 系统中,默认 core 文件的大小为0,我这里已经设置过了,显示为 core file size (blocks, -c) unlimited
如果显示为0,表示在出现 Segmentation Fault (core dump) 时不会产生 core 文件,无法通过 GDB 调试。通过 -c 参数来设置。设置好之后可以再利用上面的 -a 参数查看结果。
cv@cv:~# ulimit -c unlimited
3. 设置 core_pattern
改参数表示发送 core dump 后,对 core 文件执行什么操作。
cv@cv:~# cat /proc/sys/kernel/core_pattern core如果显示为 apport 相关的参数,表示在Ubuntu系统下,对 core dump 的处理机制是将其作为一个 bug 进行 bug 检查,如果是 bug 就上报,这种情况下我们没法用 GDB 调试我们程序的错误。
|/usr/share/apport/apport %p %s %c %P修改成 core 即可。通过下面的操作可以实现。
cv@cv: ~# sudo service apport stop
4. 设置编译参数 CMAKE_BUILD_TYPE
如果设置成 RELEASE 模式,在出现 core dump 错误时通过 GDB 显示 产生的 core 文件,可以发现信息很少,只有出现问题的函数名,当然一般也可以很轻松的定位到出错位置。
cv@cv: ~# gdb main core.31126 GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1 Copyright (C) 2016 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from main...(no debugging symbols found)...done. [New LWP 31126] Core was generated by `./main'. Program terminated with signal SIGSEGV, Segmentation fault. #0 0x0000000000401761 in github::Option::Run() () (gdb) bt #0 0x0000000000401761 in github::Option::Run() () #1 0x0000000000400ff0 in main () (gdb) q相比之下,如果设置成 DEBUG 模式,得到的信息就更丰富一些。
cv@cv: ~# gdb main core.30926 GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1 Copyright (C) 2016 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from main...done. [New LWP 30926] Core was generated by `./main'. Program terminated with signal SIGSEGV, Segmentation fault. #0 0x00000000004021c5 in github::Option::Run (this=0x7fff6ea3f6b0) at /root/mvs_project/git_repo_for_trail/src/CacheFunction.cc:42 42 std::cout << root->next->val << std::endl; (gdb) bt #0 0x00000000004021c5 in github::Option::Run (this=0x7fff6ea3f6b0) at /root/mvs_project/git_repo_for_trail/src/CacheFunction.cc:42 #1 0x0000000000401333 in main (argc=1, argv=0x7fff6ea3f7f8) at /root/mvs_project/git_repo_for_trail/main.cc:11 (gdb) q注意两种结果之中红色部分的显式信息。这里以我 Ubuntu 16.04 系统的显式为例。
5. 开始调试
比如我现在的文件结构如下
cv@cv: ~/mvs_project/git_repo_for_trail/build# tree -L 2 .. .. |-- CMakeLists.txt |-- README |-- build |-- main.cc `-- src |-- CMakeLists.txt |-- CacheFunction.cc `-- CacheFunction.h其中 CMakeLists.txt 文件内容如下
#=============================================================================== # CMAKE VERSION #=============================================================================== cmake_minimum_required(VERSION 3.5) #=============================================================================== # PROJECT CONFIG #=============================================================================== project(GIT_REPO) #=============================================================================== # CMAKE CXX_STANDARD SET, CMAKE FLAGS AND CUDA SET #=============================================================================== # when version of cmake is higher than 3.1 CMAKE_CXX_STANDARD is valid # otherwise we can just use set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") set(CMAKE_CXX_STANDARD 11) set(CMAKE_BUILD_TYPE DEBUG) #=============================================================================== # INCLUDE DIRECTORIES CONFIGURATION #=============================================================================== include_directories( src ) #=============================================================================== # SUB-DIRECTORY SET #=============================================================================== add_subdirectory(src) include_directories("src") #=============================================================================== # SOURCE FILES IN THE UPPEST FOLDER (such as main.cc CacheFunction.h # CacheFunction.cc) #=============================================================================== aux_source_directory(./src/ DIR_SRC) #=============================================================================== # EXECUTABLE PROGRAM SETTING #=============================================================================== add_executable(main main.cc ${DIR_SRC}) #=============================================================================== # TARGET LINK LIBRARIES NEEDED #=============================================================================== target_link_libraries(main src)在编译通过后运行时出现错误
cv@cv: ~/mvs_project/git_repo_for_trail/build# ./main The string elements are: h e l l o w o r l d ! 5 Segmentation fault (core dumped)此时如果按照上面的步骤设置过后,在 build 文件夹下会产生相应的 core 文件
cv@cv: ~/mvs_project/git_repo_for_trail/build# ll total 284 drwxr-xr-x 4 root root 4096 Jan 4 05:31 ./ drwxr-xr-x 5 root root 4096 Jan 4 05:31 ../ -rw-r--r-- 1 root root 11638 Jan 4 05:31 CMakeCache.txt drwxr-xr-x 5 root root 4096 Jan 4 05:31 CMakeFiles/ -rw-r--r-- 1 root root 5987 Jan 4 05:31 Makefile -rw-r--r-- 1 root root 1573 Jan 4 05:31 cmake_install.cmake -rw------- 1 root root 561152 Jan 4 05:31 core.31126 -rwxr-xr-x 1 root root 19136 Jan 4 05:31 main* drwxr-xr-x 3 root root 4096 Jan 4 05:31 src/由此我们可以进入 GDB 调试
cv@cv: ~/mvs_project/git_repo_for_trail/build# gdb main core.31126
在 GDB 环境中,上面用到的指令及其含义。
backtrace(或bt) 查看各级函数调用及参数
list(或l) 列出源代码,接着上次的位置往下列,每次列10行
quit(或q) 退出gdb调试环境
start 开始执行程序,停在main函数第一行语句前面等待命令
更多命令和技巧后续再进行补充。
参考
[1] 通过 ulimit 改善系统性能
[3] Debugging a segmentation fault using gdb
[4] gdb调试命令的使用及总结
[5] gdb Debugging Full Example (Tutorial): ncurses
[6] CppCon 2015: Greg Law 'Give me 15 minutes & I'll change your view of GDB'