GDB调试系列之基础入门(一)

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 改善系统性能

[2] 在ubuntu中进行core dump调试

[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'

posted @ 2020-01-04 14:47  coffee_tea_or_me  阅读(456)  评论(0编辑  收藏  举报