GDB学习入门之gdb准备

GDB文章目录

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



前言

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

技术鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值