GDB学习入门之gdb准备

本文涉及的产品
云原生内存数据库 Tair,内存型 2GB
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Redis 版,经济版 1GB 1个月
简介: 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 5月  13 17:10 hello
# 原始数据
[root@localhost chen]# gcc -g -o hello teststr.c 
-rwxr-xr-x.  1 root    root    9632 5月  13 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 调试的三种方法的两种,以及带着简单的例子便于理解。具体的第三种方法比较复杂,重新开一章进行详细介绍。文章给中设计的符号表信息也在未来的章节中进行简单的介绍。

相关实践学习
阿里云图数据库GDB入门与应用
图数据库(Graph Database,简称GDB)是一种支持Property Graph图模型、用于处理高度连接数据查询与存储的实时、可靠的在线数据库服务。它支持Apache TinkerPop Gremlin查询语言,可以帮您快速构建基于高度连接的数据集的应用程序。GDB非常适合社交网络、欺诈检测、推荐引擎、实时图谱、网络/IT运营这类高度互连数据集的场景。 GDB由阿里云自主研发,具备如下优势: 标准图查询语言:支持属性图,高度兼容Gremlin图查询语言。 高度优化的自研引擎:高度优化的自研图计算层和存储层,云盘多副本保障数据超高可靠,支持ACID事务。 服务高可用:支持高可用实例,节点故障迅速转移,保障业务连续性。 易运维:提供备份恢复、自动升级、监控告警、故障切换等丰富的运维功能,大幅降低运维成本。 产品主页:https://www.aliyun.com/product/gdb
目录
相关文章
|
2月前
|
NoSQL Linux 文件存储
GDB学习入门之gdb准备2
GDB学习入门之gdb准备2
39 0
GDB学习入门之gdb准备2
|
2月前
|
NoSQL 小程序 C语言
GDB调试学习(四):段错误
GDB调试学习(四):段错误
69 0
|
2月前
|
NoSQL
GDB调试学习(三):观察点
GDB调试学习(三):观察点
52 0
|
2月前
|
NoSQL
GDB调试学习(二):断点
GDB调试学习(二):断点
51 0
|
2月前
|
NoSQL IDE Linux
Linux的学习之路:8、Linux调试器-gdb使用
Linux的学习之路:8、Linux调试器-gdb使用
38 0
|
2月前
|
NoSQL Shell C语言
GDB调试学习(一):单步执行和跟踪函数调用
GDB调试学习(一):单步执行和跟踪函数调用
92 1
|
2月前
|
NoSQL 编译器 Linux
GDB 学习入门之GDB初识
GDB 学习入门之GDB初识
49 0
|
2月前
|
NoSQL Linux Android开发
OPENJTAG调试学习(三):使用 gdb 命令行进行调试
OPENJTAG调试学习(三):使用 gdb 命令行进行调试
73 0
|
2月前
|
NoSQL 搜索推荐 openCL
【C/C++ 调试 GDB指南 】gdb调试基本操作
【C/C++ 调试 GDB指南 】gdb调试基本操作
194 2
|
23天前
|
NoSQL Linux C语言
Linux gdb调试的时候没有对应的c调试信息库怎么办?
Linux gdb调试的时候没有对应的c调试信息库怎么办?
17 1