作为UNIX/Linux下使用广泛的调试器,gdb不仅提供了丰富的命令,还引入了对脚本的支持:一种是对已存在的脚本语言支持,比如python,用户可以直接书写python脚本,由gdb调用python解释器执行;另一种是命令脚本(command file),用户可以在脚本中书写gdb已经提供的或者自定义的gdb命令,再由gdb执行。在这篇文章里,我会介绍一下如何写gdb的命令脚本。

(一) 自定义命令

gdb支持用户自定义命令,格式是:

define commandName

statement

......

end

其中statement可以是任意gdb命令。此外自定义命令还支持最多10个输入参数:$arg0,$arg1 …… $arg9,并且还用$argc来标明一共传入了多少参数。

下面结合一个简单的C程序(test.c),来介绍如何写自定义命令:

#include

int global = 0;

int fun_1(void)

{

return 1;

}

int fun_a(void)

{

int a = 0;

printf("%d\n", a);

}

int main(void)

{

fun_a();

return 0;

}

首先编译成可执行文件:

gcc -g -o test test.c

接着用gdb进行调试:

[root@linux:~]$ gdb test

GNU gdb (GDB) 7.6

Copyright (C) 2013 Free Software Foundation, Inc.

License GPLv3+: GNU GPL version 3 or later

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-unknown-linux-gnu".

For bug reporting instructions, please see:

...

Reading symbols from /data2/home/nanxiao/test...done.

(gdb) b fun_a

Breakpoint 1 at 0x4004d7: file test.c, line 12.

(gdb) r

Starting program: /data2/home/nanxiao/test

Breakpoint 1, fun_a () at test.c:12

12 int a = 0;

(gdb) bt

#0 fun_a () at test.c:12

#1 0x0000000000400500 in main () at test.c:18

可以看到使用bt(backtrace缩写)命令可以打印当前线程的调用栈。我们的第一个自定义命令就是也实现一个backtrace功能:

define mybacktrace

bt

end

怎么样?简单吧,纯粹复用gdb提供的命令。下面来验证一下:

(gdb) define mybacktrace

Type commands for definition of "mybacktrace".

End with a line saying just "end".

>bt

>end

(gdb) mybacktrace

#0 fun_a () at test.c:12

#1 0x0000000000400500 in main () at test.c:18

功能完全正确!

接下来定义一个赋值命令,把第二个参数的值赋给第一个参数:

define myassign

set var $arg0 = $arg1

end

执行一下:

(gdb) define myassign

Type commands for definition of "myassign".

End with a line saying just "end".

>set var $arg0 = $arg1

>end

(gdb) myassign global 3

(gdb) p global

$1 = 3

可以看到global变量的值变成了3。

对于自定义命令来说,传进来的参数只是进行简单的文本替换,所以你可以传入赋值的表达式,甚至是函数调用:

(gdb) myassign global fun_1()

(gdb) p global

$2 = 1

可以看到global变量的值变成了1。

除此以外,还可以为自定义命令写帮助文档,也就是执行help命令时打印出的信息:

document myassign

assign the second parameter value to the first parameter

end

执行help命令:

(gdb) document myassign

Type documentation for "myassign".

End with a line saying just "end".

>assign the second parameter value to the first parameter

>end

(gdb) help myassign

assign the second parameter value to the first parameter

可以看到打印出了myassign的帮助信息。

(二) 命令脚本

首先对于命令脚本的命名,其实gdb没有什么特殊要求,只要文件名不是gdb支持的其它脚本语言的文件名就可以了(比如.py)。因为这样做会使gdb按照相应的脚本语言去解析命令脚本,结果自然是不对的。

其次为了帮助用户写出功能强大的脚本,gdb提供了如下的流程控制命令:

(1)条件命令:if...else...end。这个同其它语言中提供的if命令没什么区别,只是注意结尾的end。

(2)循环命令:while...end。gdb同样提供了loop_break和loop_continue命令分别对应其它语言中的break和continue,另外同样注意结尾的end。

另外gdb还提供了很多输出命令。比方说echo命令,如果仅仅是输出一段文本,echo命令特别方便。此外还有和C语言很相似的支持格式化输出的printf命令,等等。

脚本文件的注释也是以#开头的,这个同很多其它脚本语言都一样。

最后指出的是在gdb中执行脚本要使用source命令,例如:“source xxx.gdb”。

(三) 一个完整的例子

最后以一个完整的gdb脚本(search_byte.gdb)做例子,来总结一下本文提到的内容:

define search_byte

if $argc != 3

help search_byte

else

set $begin_addr = $arg0

set $end_addr = $arg1

while $begin_addr <= $end_addr

if *((unsigned char*)$begin_addr) == $arg2

printf "Find it!The address is 0x%x\n", $begin_addr

loop_break

else

set $begin_addr = $begin_addr + 1

end

end

if $begin_addr > $end_addr

printf "Can't find it!\n"

end

end

end

document search_byte

search a specified byte value(0 ~ 255) during a memory

usage: search_byte begin_addr end_addr byte

end

这个脚本定义了search_byte命令,目的是在一段指定内存查找一个值(unsigned char类型):需要输入内存的起始地址,结束地址和要找的值。

命令逻辑可以分成3个部分:

(a) 首先判断输入参数是不是3个,如果不是,就输出帮助信息;

(b) 从起始地址开始查找指定的值,如果找到,打印地址值并退出循环,否则把地址加1,继续查找;

(c) 如果在指定内存区域没有找到,打印提示信息。

另外这个脚本还定义了search_byte的帮助信息。

仍然以上面的C程序为例,来看一下如何使用这个gdb脚本:

[root@linux:~]$ gdb test

GNU gdb (GDB) 7.6

Copyright (C) 2013 Free Software Foundation, Inc.

License GPLv3+: GNU GPL version 3 or later

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-unknown-linux-gnu".

For bug reporting instructions, please see:

...

Reading symbols from /data2/home/nanxiao/test...done.

(gdb) p &global

$1 = (int *) 0x600900

(gdb) p global

$2 = 0

(gdb) source search_byte.gdb

(gdb) search_byte 0x600900 0x600903 0

Find it! The address is 0x600900

(gdb) search_byte 0x600900 0x600903 1

Can't find it!

可以看到global的值是0,起始地址是0x600900,结束地址是0x600903。在global的内存区域查找0成功,查找1失败。

受篇幅所限,本文只是对gdb命令脚本做了一个粗浅的介绍,旨在起到抛砖引玉的效果。如果大家想更深入地了解这部分知识,可以参考gdb手册的相关章节:Extending GDB (https://sourceware.org/gdb/onlinedocs/gdb/Extending-GDB.html)。最后向大家推荐一个github上的.gdbinit文件:https://github.com/gdbinit/Gdbinit/blob/master/gdbinit,把这个弄懂,相信gdb脚本文件就不在话下了。

linux gdb 脚本,如何写gdb命令脚本相关推荐

  1. Linux学习系列五:Shell命令脚本的基本语法

    这个系列的Linux教程主要参考刘遄老师的<Linux就该这么学>.用的系统是RHEL8,如果遇见一些命令出现问题,请首先检查自己的系统是否一致,如果不一致,可网上查一下系统间某些命令之间 ...

  2. 卷毛崽|Linux自学|Vim 编辑器与 Shell 命令脚本

    Vim编辑器与 Shell 命令脚本 1.Vim 文本编辑器: (1) vim常见命令 (2) vim 更改主机名(RHCSA考题) (3)vim 配置网卡ip(RHCSA考题) (4) vim配置y ...

  3. python自动化测试脚本怎么写_自动化测试脚本一般用什么语言写

    1. 自动化测试脚本一般用什么语言写 我主要是做web测试的,最近也在研究自动化测试. 自动化测试主流的工具应该是QTP吧,这个你可以去51testing论坛搜到很多相关的资料.QTP是一个商业软件. ...

  4. 订单流失总金额怎么算_抖音直播脚本怎么写?直播脚本创作必备的7大要素

    你直播时,是不是也遇到过这样的问题: 抖音直播脚本 不知道如何讲解产品:不知道如何回答粉丝的问题:不知道在讲述什么重点又是什么:面对一些粉丝的尖锐问题会手举无措:没有话题强行尬聊-- 近年来,随着抖音 ...

  5. Linux:使用select PS3写一个名单脚本

    select循环比较少用,写个脚本练练手. #!/bin/bash PS3="学员名单管理系统(1-5)" while true; doselect choice in " ...

  6. 路由器运行python脚本_写个Python脚本来登录小米路由器

    这个脚本写起来难度并不是很大,博主还是一步步的分析下,这样思路会比较清晰,下次遇到类似系统脚本写起来也更快速.好了,一起来分析分析. 首先看下小米路由器的登录界面 可以看到只需要输入密码即可登录,博主 ...

  7. linux写一个ls命令,linux 下 如何自己写 ls 命令

    有过linux 基础 都知道 ls 命令的作用 下面给出实现代码 #include #include #include #include #include #include #include #inc ...

  8. html如何调用短视频文件,短视频脚本怎么写?3种短视频脚本的创意写作方法干货分享!...

    短视频的崛起给了很多人发挥才能.自主创业的机会.而要想从短视频流量巨海中脱颖而出,除了本身所具备的才能外,还要求我们在短视频内容创作时有令人惊叹的创意. 其中,短视频脚本创作就是一个关键环节. 那么, ...

  9. linux设置开机自启某个命令

    一 . linux开机自启某个指令 步骤1:编辑 /etc/rc.local 文件 vim /etc/rc.local 步骤2:在文件底部加入需要执行的命令,示例如下: #!/bin/bash #TH ...

最新文章

  1. 苏大微型计算机原理与应用题库,苏大单片机原理及应用试卷
  2. linux 下进入oracle,linux 下的oracle怎么启动
  3. 垂直居中相关知识总结
  4. ICPC 南昌现场赛 K:Tree(dsu on tree + 动态开点线段树)
  5. JPA 2.1:不同步的持久性上下文
  6. [妙味DOM]第五课:事件深入应用
  7. matlab与python实现神经网络_Adaline神经网络简单介绍和MATLAB简单实现
  8. oracle执行外部sql_增强的PolyBase SQL 2019-Oracle DB的外部表
  9. 第6章 旋转的方块(《Python趣味创意编程》教学视频)
  10. 设置时间同步(ntp)详细步骤
  11. Asp.net MVC 自定义路由
  12. 【微信小程序】从零开始搭建一个英语学习小程序01——基础准备
  13. 二叉树【按层打印、序列化、反序列化】
  14. 服务器如何查看 网站访问记录,如何查看服务器远程的访问记录
  15. 疯狂的 ICO 终于被全面叫停;9 月全球数据库排名,Oracle 跌势明显
  16. 爬取《斗破苍穹》小说
  17. linux 安装手机usb驱动
  18. CDH kudu Unable to load consensus metadata for tablet
  19. JVM能够开启多少线程
  20. 多媒体封装格式详解---MP4

热门文章

  1. Ubuntu的奇技淫巧
  2. position:搜索框显示历史浏览记录
  3. loj#2340. 「WC2018」州区划分
  4. 读取设置config.ini配置
  5. 数据分析系统DIY1/3:CentOS7+MariaDB安装纪实
  6. 【折腾的一个小玩意】基于jquery+百度音乐的音乐外链小工具
  7. wcf分布式构架集群案例解决方案
  8. 电子邮件地址抓取工具
  9. Android--使用LayoutInflater加载布局文件的三种方法
  10. react+redux+antd图书管理系统学习