GDB学习入门之gdb准备

GDB文章目录

第一章 GDB 学习入门之GDB初识
第二章 GDB学习入门之gdb准备


文章目录

  • GDB文章目录
  • 前言
  • 一、调试信息
    • 1. 例子
    • 2.如何判断是否带有调试信息
      • 3.如何编译的时候链接符号信息
  • 二、GDB启动调试
    • 1.直接调试目标程序
    • 2.附加进程调试
      • 例如 调试redis
    • 3.调试core文件
  • 总结


前言

gdb的背景前面已经介绍:

根据上一章的介绍,此章节主要是对于调试方式如何使用的的深入介绍。


一、调试信息

gcc 编译生成的执行程序,需要包含调试信息(符号表中的信息)
一般要调试某个程序,为了能清晰地看到调试的每一行代码、调用的堆栈信息、变
量名和函数名等信息,需要调试程序含有调试符号信息。使用 gcc 编译程序时,如果加
上· -g ·选项即可在编译后的程序中保留 调试符号信息。

1. 例子

如何生成带符号信息的执行程序:

例如: hello.c

gcc -g -o hello hello.c

2.如何判断是否带有调试信息

我们可以使用 gdb 来调试一下这个程序, gdb 会显示正确读取到该程序的调试信息,在打开的 Linux Shell 终端输入 gdb hello_server 查看显示结果即可:

[root@localhost chen]# gdb hello 
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-120.el7
Copyright (C) 2013 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-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/chen/hello...done.
(gdb) 

GDB加载成功之后,会出现如下的信息,
Reading symbols from /home/chen/hello...done.


** 未使用-g 编译生成的执行程序**

编译: gcc -o hello2 hello.c
Reading symbols from /home/chen/hello2…(no debugging symbols found)…done.
(gdb)

3.如何编译的时候链接符号信息

方法一: 程序编译的时候不加上-g
方法二:使用命令剔除符号信息(strip

[root@localhost chen]# strip hello
-rwxr-xr-x.  1 root    root    6256 513 17:10 hello

# 原始数据
[root@localhost chen]# gcc -g -o hello teststr.c 
-rwxr-xr-x.  1 root    root    9632 513 17:11 hello

[root@localhost chen]# nm hello
0000000000601044 B __bss_start
0000000000601044 b completed.6355
0000000000601040 D __data_start
0000000000601040 W data_start
0000000000400510 t deregister_tm_clones
0000000000400580 t __do_global_dtors_aux
0000000000600e18 t __do_global_dtors_aux_fini_array_entry
00000000004006c8 R __dso_handle
0000000000600e28 d _DYNAMIC
0000000000601044 D _edata
0000000000601048 B _end
00000000004006b4 T _fini
00000000004005a0 t frame_dummy
0000000000600e10 t __frame_dummy_init_array_entry
0000000000400870 r __FRAME_END__
0000000000601000 d _GLOBAL_OFFSET_TABLE_
                 w __gmon_start__
000000000040074c r __GNU_EH_FRAME_HDR
0000000000400458 T _init
0000000000600e18 t __init_array_end
0000000000600e10 t __init_array_start
00000000004006c0 R _IO_stdin_used
0000000000600e20 d __JCR_END__
0000000000600e20 d __JCR_LIST__
00000000004006b0 T __libc_csu_fini
0000000000400640 T __libc_csu_init
                 U __libc_start_main@@GLIBC_2.2.5
00000000004005cd T main
                 U printf@@GLIBC_2.2.5
                 U puts@@GLIBC_2.2.5
0000000000400540 t register_tm_clones
00000000004004e0 T _start
                 U strcasestr@@GLIBC_2.2.5
0000000000601048 D __TMC_END__
[root@localhost chen]# strip hello
[root@localhost chen]# nm hello
nm: hello:无符号

二、GDB启动调试

1.直接调试目标程序

调试方法:
gdb file_name (gdb hello)

此方法是最简单的调试方法,只要确定程序中存在符号信息,就可以使用gdb 直接调试

2.附加进程调试

调试方法:
gdb attach pid 附加进程调试,需要加上权限sudo
相关命令: 分离关联 detaach
某些情况下程序已经在运行,我们想调试这个程序,但是又不想重启这个程序,我们可以使用采用附加进程的调试方式。这种方式当调试完程序想结束此次时, 而且不对当前进程 有任何影响。

例如 调试redis

第一步骤:获取程序id

[root@localhost ~]# ps -ef|grep redis
root     17259     1  0 16:29 ?        00:00:25 /usr/local/redis/bin/redis-server *:6379
root     26105 25828  0 23:10 pts/3    00:00:00 grep --color=auto redis

获取redis 的进程PID为17259,然后使用gdb attach17259(注意权限问题,加上sudo),既是 sudo gdb attach 17259.

[root@localhost ~]# sudo gdb attach 17259
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-120.el7
Copyright (C) 2013 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-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
attach: 没有那个文件或目录.
Attaching to process 17259
Reading symbols from /usr/local/redis/bin/redis-server...done.
Reading symbols from /lib64/libm.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib64/libm.so.6
Reading symbols from /lib64/libdl.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib64/libdl.so.2
Reading symbols from /lib64/librt.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib64/librt.so.1
Reading symbols from /lib64/libpthread.so.0...(no debugging symbols found)...done.
[New LWP 4411]
[New LWP 17271]
[New LWP 17270]
[New LWP 17269]
[New LWP 17268]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Loaded symbols for /lib64/libpthread.so.0
Reading symbols from /lib64/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib64/libc.so.6
Reading symbols from /lib64/ld-linux-x86-64.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
0x00007ffff71e20e3 in epoll_wait () from /lib64/libc.so.6
Missing separate debuginfos, use: debuginfo-install glibc-2.17-325.el7_9.x86_64
(gdb) 

当用 gdb attach 上目标进程后,调试器会暂停下来,此时可以使用 continue ©命令让程序继续执行,或者添加断点然后在继续执行。当调试完程序想结束此次时, 而且不对当前进程 redis有任何影响.

程序分离gdb 调试,可以在gdb的命令界面中输入detach命令程序和gdb调试器分离,这样redis就可以继续运行了。

// 程序和gdb调试器分离
(gdb) detach
Detaching from program: /usr/local/redis/bin/redis-server, process 17259
[Inferior 1 (process 17259) detached]
(gdb) 

3.调试core文件

调试方法:
gdb filename corename 调试core 文件
此方法涉及的信息比较多下一章节详细介绍


总结

此章节详细介绍了gdb 调试的三种方法的两种,以及带着简单的例子便于理解。具体的第三种方法比较复杂,重新开一章进行详细介绍。文章给中设计的符号表信息也在未来的章节中进行简单的介绍。

你可能感兴趣的:(编译调试工具,linux)