gdb基础命令和常用操作补充

GDB是Unix下的一个程序调试工具,类似于windows下面的VC调试器,区别在于GDB采用全命令行控制。

使用GDB需要在编译时使用-g选项,gcc支持-g –O选项同时使用,但如果还在调试阶段,尽量不要-O2,也不要删除(strip)符号表。作用如下:

让程序按照自己定义的要求运行,不必每次改变程序 让程序在设置的断点处停住,并且检查程序的执行情况 动态改变程序的执行环境

一、启动调试

gdb <program> 启动程序进行调试 gdb ./bin/chat_server gdb --args ./bin/chat_server -c conf/cache_server.conf 在 UNIX 下用 ps 查看正在运行的程序的 PID (进程 ID), 然后用 gdb <program> PID 格式挂接正在运行的程序。

gdb attach <pid> 调试一个已经运行服务程序 gdb ./bin/chat_server $(pgrep  chat_server) gdb <program> core 调试程序core down时候产生的core文件  gdb ./bin/chat_server core

可以先使用 gcore pid (tgid,主线程id)产生正在运行程序的 core 文件,然后进行调试。

Attach到后台进程,将操作预先输入好,避免影响程序正常运行

sudo gdb ./bin/chat_server `pgrep chat_server` <<END b HandleAccept c p (char *)inet_ntoa(pstSctx->stClientAddr.sin_addr) p ntohs(pstSctx->stClientAddr.sin_port) quit END

二、gdb基础命令

三、gdb常用操作补充

1. ulimit -c unlimited; 调试core文件

bt/where/info s 显示函数调用堆栈

up n 向调用链根部移动n个函数

down n 向调用链叶部移动n个函数

f n 选择函数调用链上编号为n的函数,0表示当前函数

info files 显示core文件里面的segment映射 如果core文件函数调用栈乱掉,可以参照 http://devpit.org/wiki/x86ManualBacktrace 恢复堆栈。

2. 设置观察点

watch     <expr>  expr 值变化时,停止程序

rwatch    <expr>  expr 值被读时,停止程序

awatch    <expr>  expr 值被读或被写时,停止程序

info watchpoints  查看当前观察点信息

3.反汇编

set disassembly-flavor intel # 设置反汇编格式 disassemble可以反汇编当前函数或者指定的函数,单独用disassemble命令是反汇编当前函数,如果disassemble命令后面跟函数名或地址则反汇编指定的函数。

4.前面讲过step命令可以一行代码一行代码地单步调试,而这里用到的si/ni命令可以一条指令一条指令地单步调试。

info registers可以显示所有寄存器的当前值。在gdb中表示寄存器名时前面要加个$,例如p $esp可以打印esp寄存器的值,如esp寄存器的值是0xbff1c3f4,所以x/20 $esp命令查看内存中从0xbff1c3f4地址开始的20个32位数。

5. p 命令内存输出格式: • d: ⼗十进制 • u: ⼗十进制⽆无符号 • x: ⼗十六进制 • o: ⼋八进制 • t: ⼆二进制 • c:   字符

如 p/x var

6. set listsize 50 修改源代码显示行数; 此外还有set args 设置参数;set var 设置变量值

7.设置位置断点,设置断点命令b (break的简写) b linenum b function b filename:linenum b filename:function b *address b if <condition>

8. 查看当前运行信息 info b <breakpoints>  breakpoints 为设置的断点的标号 info args/frame/locals/line  filename:function info line 配合disassemble使用可查看程序汇编代码

其中info frame 显示的当前堆栈信息比frame详细,可以先用frame num 切换堆栈,where/info s/bt 可以查看堆栈调用链

9. 条件式中断 b test if a == 10  类似 condition 4 a == 30 (4 是bk num)

10. 删除断点可以使用 clear和d(delete的简写)

clear删除断点, 使用方法和b命令类似

d  [breakpoints]    breakpoints 为设置的断点的标号

10. 启动和查看程序

setargs 设置程序运行参数

run运行程序,使用方式如:r   <args>

List  显示程序源代码命令,使用show listsize 查看显示代码的行数

  list <function/linenum/filename:function/filename:linenum/-/+> ,-向上翻动,+向下翻动

p var/expression(filename::var/function::var),打印变量值

11. 恢复运行程序和单步调试程序

continue,继续运行程序

next  <count> 单步跟踪,遇到函数不进入函数

step  <count> 单步跟踪,遇到函数会进入该函数

finish 直到函数运行完成,打印函数信息

until   在循环体内跟踪程序,直到整个循环结束

until+行号: 运行至某行,不仅仅用来跳出循环

12. x 命令可以显示指定地址的内存数据。 格式: x/nfu [address] • n: 显示内存单位 (组或者行)。 • f: 格式 (除了print 格式外,还有字符串s 和 汇编i)。 • u: 内存单位 (b: 1字节; h: 2字节; w: 4字节; g: 8字节)。

x/8w 0x0804843b # 按四字节(w)显示 8组内存数据 x/8i 0x0804843b # 显示8 行汇编指令

13. 进程与线程

info proc mappings # 相当于 cat /proc/{pid}/maps 查看maps内存数据

可以在 pthread_create 处设置断点,当线程创建时会生成提示信息。[New Thread 0xb7e78b70 (LWP 2933)]

info threads # 查看所有线程列表

where # 显示当前线程调用堆栈

thread num # 切换线程 [Switching to thread 1 (Thread 0xb7e796c0 (LWP 2932))]#0 0xb7fe2430 in __kernel_vsyscall ()

14. 其他零散

调试子进程。 (gdb) set follow-fork-mode child

临时进入Shell执行命令,Exit返回。 (gdb) shell

调试时直接调用函数。 (gdb) call test("abc")

使用 "--tui" 参数,可以在终端窗口上部显示一个源代码查看窗。 $ gdb --tui hello

set scheduler-locking off|on|step 在使用step或者continue命令调试当前被调试线程的时候,其他线程也是同时执行的,怎么只让被调试程序执行呢?通过这个命令就可以实现这个需求。

off 不锁定任何线程,也就是所有线程都执行,这是默认值。 on 只有当前被调试程序会执行。 step 在单步的时候,除了next过一个函数的情况(熟悉情况的人可能知道,这其实是一个设置断点然后continue的行为)以外,只有当前线程会执行。

在GDB下,我们无法print宏定义,因为宏是预编译的。但是我们还是有办法来调试宏,这个需要GCC的配合。在GCC编译程序的时候,加上-ggdb3参数,这样,你就可以调试宏了。另外,你可以使用下述的GDB的宏调试命令 来查看相关的宏。

info macro – 你可以查看这个宏在哪些文件里被引用了,以及宏定义是什么样的。 macro – 你可以查看宏展开的样子。

提示找不到源文件:

编译程序员是否加上了-g参数以包含debug信息。 路径是否设置正确了。使用GDB的directory命令来设置源文件的目录。

如果要打印一个序列化过的结构体,这个序列太长的话,往往会被gdb省略掉,如: gdb>p string "xxxx",…"" //会有省略号出现,无法看到完整的字符串 此时可以设置: gdb>set print elements 0 再次: gdb>p string "xxxx","yyyy",""//显示完整的字符串

查看命令帮助。 (gdb) help b

最后就是退出命令。 (gdb) q

和Linux Base Shell习惯一样,对于记不住的命令,可以在输入前几个字母后按Tab补全。 ▪ tbreak          temporary breakpoint ▪ rbreak          reg-ex breakpoint ▪ break xxx if yyy    conditionally break at xxx if condition yyy holds ▪ commands         list of commands to be executed when a breakpoint is hit ▪ silent          special command to suppress output on breakpoint hit ▪ save breakpoints    save a list of breakpoints to a script ▪ save history       save history of executed gdb commands ▪ call            call a function in the inferior ▪ watch -l          watchpoint based on address (location) ▪ rwatch           read watchpoint ▪ info line foo.c:42   show PC for line ▪ info line * $pc     show line begin/end for current program counter ▪ thread apply all bt   backtrace for every thread ▪ dprintf           dynamic printf ▪ python:           define custom commands by inheriting from gdb.Command class ▪ python:           hook events to invoke python functions using gdb.events.stop.connect ▪ gcc’s -g and -O are orthogonal

经验:如果某个函数的局部变量发生访问越界,有可能并不立即产生段错误,而是在函数返回时产生段错误。

参考:

《linux c 编程一站式学习》 《C 学习笔记》 by雨痕

Give me fifteen minutes and I’ll change your view of GDB

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏程序员的碎碎念

php写接口入门

了解JSON JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation) JSON 是轻量级的文本数据交换格式 ...

6037
来自专栏Django Scrapy

python3 下调用zabbix api 获取多个机房的IP

根据工作的需要,需要查看监控中的所有ip,我们一共有三个机房,每个机房都部署了同样的zabbix监控 根据三个园区的 监控api的url 实现功能:不输入参数 ...

3085
来自专栏开发与安全

linux系统编程之进程(三):exec系列函数和system函数

一、exec替换进程映象 在进程的创建上Unix采用了一个独特的方法,它将进程创建与加载一个新进程映象分离。这样的好处是有更多的余地对两种操作进行管理。当我们创...

2076
来自专栏小尘哥的专栏

springboot使用properties定义短信模板

通常我们做开发时候会遇到短信发送邮件发送之类的需求,发送内容往往会由客户提供一个模板,如果我们是在程序里拼接字符串来搞定这个模板,很明显是一种坑队友的做法。一般...

673
来自专栏林德熙的博客

win10 uwp 通知列表

经常看到小伙伴问,问已经绑定列表,在进行修改时,不会通知界面添加或删除。这时问题就在,一般使用的列表不会在添加时通知界面,因为他们没有通知。 本文:知道什么是通...

401
来自专栏技术小黑屋

Ruby执行shell命令的六种方法

在Ruby中,执行shell命令是一件不奇怪的事情,Ruby提供了大概6种方法供开发者进行实现。这些方法都很简单,本文将具体介绍一下如何在Ruby脚本中进行调用...

812
来自专栏十月梦想

node读取目录下文件,筛选文件夹和文件!

node也学习了几天,今天讲解一下刚学习的小案例!使用fs模块fs.readdir读取只能目录下文件,筛选文件和文件夹

702
来自专栏前端知识分享

第218天:Angular---模块和控制器

所有需要ng管理的代码必须被包裹在一个有ng-app指令的元素中 ng-app是ng的入口,表示当前元素的所有指令都会被angular管理(对每一个指令进行分析...

692
来自专栏Java 源码分析

MyBatis笔记二:配置

可以看到我们使用 <properties resource="db.properties"/> 引入了我们的数据据库的配置文件,然后这个标签有两个属性 : r...

1542
来自专栏青枫的专栏

Linux下gdb的安装及使用入门

用root权限的Terminal(或一般权限的Terminal)的vi编辑器编写一个C程序a.c:

611

扫码关注云+社区