分享

GDB MI 命令介绍

 幸福的乐土 2012-01-09
libgdb过时了,目前的GDB调试前端都不用libgdb

目前有两种比较流行:
- MI接口,现在应该是MI II接口,是Eclipse CDT所采用的方式
- emac输出接口,这个似乎有更多的调试前端所采用,例如DDD,kdbg,codeblocks等等

另外还有一种比较另类的一种方式:insight,直接把gdb给包含进去了

=========================================

GDB MI Interface

虽 然使用GDB已经很多年了,但是直到最近因为工作需要才知道GDB除了CLI(Commnad Line Interface)命令外,还有一个更重要的MI (Machine Interface)命令。之所以“更重要”,因为MI不但包括了CLI的所有命令,还具备一些CLI所不提供的功能。当然,MI接口的设计初衷是面向将 GDB作为系统组件之一的复杂系统。在类似于DDD,Insight等以GDB为backend的GUI debugger的实现中,就是充分利用了GDB MI接口。MI最大的不足在于其输出比较复杂,必须很熟悉其输出格式才能理解,不如CLI输出直观。但这只是习惯问题,多用多读自然就OK啦。
 
简单地说,GDB MI interpreter 接受字符串形式的命令输入,然后产生一行表示命令执行结果的输出。当然,这里的输入命令和输出记录都有严格的格式和内容定义。而且,根据命令的不同(同步 命令或异步命令),GDB的输出也代表不同的含义。当利用GDB MI实现一个GUI的debugger时,通常的做法是使用一个进程负责管理GDB,将GDB作为其子进程派生出来后,接管其标准I/O,并通过pipe 向GDB注入MI命令,并接收GDB MI输出。自然,该进程的另一个工作就是与GUI前端交互,完成GUI命令解析以及返回相应record.
 
Insight使用Tcl/tk实现前端GUI,DDD使用的则是Gtk。前段时间正好学习了Python,是不是可以用Python+GDB MI来作一个GUI Debugger?正好还可以复习一下前一阵子看过的程序link and load 过程。
 
注:GDB MI的详细介绍参见GDB 手册: Debugging with GDB.其中专门一章讨论MI接口。

==================================

对于gdb的命令很多人可能都已经很熟悉了,本文介绍的mi层命令可能很少有人用到,它也是gdb的一部分,主要目的是为一些目标系统如IDE等提 供调试功能,如eclipse下c/c++的cdt插件的底层就是调用的mi层命令,cdt的包里面有两个类RxThread,TxThread就是一个 发送mi命令,一个接收返回数据的,大家有兴趣可以研究下。

mi的命令依然是以文本行方式提供的,并兼容我们常用的gdb CLI命令,下面我们看一下它的进入和退出:

进入命令 gdb --interpreter mi ****.exe

退出命令 quit

效果如下:

libo@libo-desktop:~$ gdb --interpreter mi
~"GNU gdb (GDB) 7.1-ubuntu\n"
~"Copyright (C) 2010 Free Software Foundation, Inc.\n"
~"License GPLv3+: GNU GPL version 3 or later <http:///licenses/gpl.html>\n"
~"This is free software: you are free to change and redistribute it.\n"
~"There is NO WARRANTY, to the extent permitted by law.  Type \"show copying\"\n"
~"and \"show warranty\" for details.\n"
~"This GDB was configured as \"i486-linux-gnu\".\n"
~"For bug reporting instructions, please see:\n"
~"<http://www./software/gdb/bugs/>.\n"
=thread-group-created,id="42000"
=thread-created,id="1",group-id="42000"
*stopped,frame={addr="0x00000000",func="??",args=[]},thread-id="1",stopped-threads="all"
@"JTAG speed set to 100 kHz\r\n"
@"Target endianess set to \"little endian\"\r\n"
@"Select flash device: STM32F103RB\r\n"
@"Flash download enabled\r\n"
@"Flash breakpoints enabled\r\n"
@"Resetting target\r\n"
@"Sleep 500ms\r\n"
@"Writing register (SP = 0x20005000)\r\n"
@"Writing register (PC = 0x08001739)\r\n"
(gdb)
quit
&"quit\n"
=thread-group-exited,id="42000"
libo@libo-desktop:~$

mi的命令总共分为以下几个部分:

1.断点(Breakpoint)

2.程序环境(Program Context)

3.线程(Thread)

4.程序执行(Program Execution)

5.栈(Stack)

6.变量(Variable)

7.数据(Data)

8.跟踪点(Tracepoint)

9.符号(Symbol)

10.文件(File)

11.目标数据(Target Manipulation)

12.其它杂项

我们以下面这段代码为例演示各种命令的执行结果:

/*
** demo.c
*/


#include 
<stdio.h>

int swap(int a[], int len)
{
    
int i;

    int temp;

    
for(i = 0; i < len / 2; i++)
    
{
        temp 
= a[i];
        a[i] 
= a[len - i - 1];
        a[len 
- i - 1= temp;
    }


    
return 0;
}


int main()
{
    
int array[10];
    
int i;
    
    
for(i = 0; i < 10; i++)
        array[i] 
= i;
    printf(
"swap before:");
    
for(i = 0; i < 10; i++)
        printf(
"%d ", array[i]);
    printf(
" \n");

    swap(array, 
10);

    printf(
"swap after:");
    
for(i = 0; i < 10; i++)
        printf(
"%d ", array[i]);
    printf(
" \n");

    
return 0;
}


执行gcc  -g demo.c -o demo.exe编译。

具体详细的命令还请大家看gdb手册,下面一一介绍:

1.断点

-break-after

用法:-break-after number count
语义:第number个断点在被执行count次后有效

-break-condition

用法:-break-condition number expr
语义:第number个断点在表达式expr为true时有效

-break-delete

用法:-break-delete ( breakpoint number )+
语义:删除指定number 的多个断点

-break-disable

用法:-break-disable ( breakpoint number)+
语义:使指定number的多个断点失效

-break-enable

用法:-break-enable ( breakpoint number)+
语义:使指定number的多个断点起效

-break-info

用法:-break-info breakpoint
语义:得到指定断点的信息

-break-insert

用法:

 -break-insert [ -t ] [ -h ] [ -r ]
[ -c condition ] [ -i ignore-count ]
[ -p thread ] [ line | addr ]
语义:-t 插入一个临时断点
-h 插于一个硬件端点
-r 插入一个正则断点,当函数名匹配正则表达式时有效
-c 插入一个条件断点
-i 插入一个指定无效次数的断点
如果指定了line选项,可以使用如下格式:
函数
文件名:行号
文件名:函数
地址
-break-list 
用法:-break-list
语义:先是已插入断点的列表
-break-watch 
用法:-break-watch [ -a | -r ] variable
语义:创建一个观察点,-a表示对variable读写时有效,-r表示只读时有效
运行效果:
libo@libo-desktop:~/temp$ gdb --interpreter mi demo.exe
也可以先运行 gdb --interpreter mi 然后在用加载文件  file /home/libo/temp/demo.exe

注意:命令中间有无短横线是有区别的,最好是加上短横线。比如下面:
(gdb)
break insert main
&"break insert main\n"
&"Function \"insert\" not defined.\n"
~"Breakpoint 5 (insert main) pending.\n"
^done
这里没加横线,提示insert命令没有定义,但是后面行却显示执行了这条命令(断点已经加上了)。

(gdb)
-break-insert main
^done,bkpt={number="4",type="breakpoint",disp="keep",enabled="y",addr="0x08048498",func="main",file="demo.c",fullname="/home/libo/temp/demo.c",line="23",times="0",original-location="main"}

(gdb)
-break-insert 28
^done,bkpt={number="3",type="breakpoint",disp="keep",enabled="y",addr="0x080484f6",func="main",file="demo.c",fullname="/home/libo/temp/demo.c",line="28",times="0",original-location="demo.c:28"}
(gdb)
-break-list
^done,BreakpointTable={nr_rows="2",nr_cols="6",hdr=[{width="7",alignment="-1",col_name="number",colhdr="Num"},{width="14",alignment="-1",col_name="type",colhdr="Type"},{width="4",alignment="-1",col_name="disp",colhdr="Disp"},{width="3",alignment="-1",col_name="enabled",colhdr="Enb"},{width="10",alignment="-1",col_name="addr",colhdr="Address"},{width="40",alignment="2",col_name="what",colhdr="What"}],body=[bkpt={number="1",type="breakpoint",disp="keep",enabled="y",addr="<PENDING>",pending="list",times="0",original-location="list"},bkpt={number="2",type="breakpoint",disp="keep",enabled="y",addr="<PENDING>",pending="insert main",times="0",original-location="insert main"}]}

(gdb)
-exec-run
=thread-group-created,id="19676"
=thread-created,id="1",group-id="19676"
^running
*running,thread-id="all"
(gdb)
=library-loaded,id="/lib/ld-linux.so.2",target-name="/lib/ld-linux.so.2",host-name="/lib/ld-linux.so.2",symbols-loaded="0"
=library-loaded,id="/lib/tls/i686/cmov/libc.so.6",target-name="/lib/tls/i686/cmov/libc.so.6",host-name="/lib/tls/i686/cmov/libc.so.6",symbols-loaded="0"
*stopped,reason="breakpoint-hit",disp="keep",bkptno="4",frame={addr="0x08048498",func="main",args=[],file="demo.c",fullname="/home/libo/temp/demo.c",line="23"},thread-id="1",stopped-threads="all",core="1"

(gdb)
-exec-continue
^running
*running,thread-id="1"
(gdb)
*stopped,reason="breakpoint-hit",disp="keep",bkptno="3",frame={addr="0x080484f6",func="main",args=[],file="demo.c",fullname="/home/libo/temp/demo.c",line="28"},thread-id="1",stopped-threads="all",core="1"

(gdb)
-break-delete 1
^done
(gdb)
-break-list
^done,BreakpointTable={nr_rows="5",nr_cols="6",hdr=[{width="7",alignment="-1",col_name="number",colhdr="Num"},{width="14",alignment="-1",col_name="type",colhdr="Type"},{width="4",alignment="-1",col_name="disp",colhdr="Disp"},{width="3",alignment="-1",col_name="enabled",colhdr="Enb"},{width="10",alignment="-1",col_name="addr",colhdr="Address"},{width="40",alignment="2",col_name="what",colhdr="What"}],body=[bkpt={number="2",type="breakpoint",disp="keep",enabled="y",addr="<PENDING>",pending="insert main",times="0",original-location="insert main"},bkpt={number="3",type="breakpoint",disp="keep",enabled="y",addr="0x080484f6",func="main",file="demo.c",fullname="/home/libo/temp/demo.c",line="28",times="1",original-location="demo.c:28"},bkpt={number="4",type="breakpoint",disp="keep",enabled="y",addr="0x08048498",func="main",file="demo.c",fullname="/home/libo/temp/demo.c",line="23",times="1",original-location="main"},bkpt={number="5",type="breakpoint",disp="keep",enabled="y",addr="<PENDING>",pending="insert main",times="0",original-location="insert main"},bkpt={number="6",type="breakpoint",disp="keep",enabled="y",addr="<PENDING>",pending="list",times="0",original-location="list"}]}

2.程序环境
-exec-arguments 
用法:-exec-arguments args
语义:设置程序命令行参数
-exec-show-arguments 
用法:-exec-show-arguments
语义:显示命令行参数
-environment-cd 
用法:-environment-cd pathdir
语义:设置GDB的工作目录
-environment-directory 
用法:-environment-directory [ -r ] [ pathdir ]+
语义:添加一个或多个pathdir到源文件的搜索路径,如果"-r"被指定,pathdir将被设为缺省的搜索路径
-environment-path 
用法:-environment-path [ -r ] [ pathdir ]+
语义:添加一个或多个pathdir到目标文件的搜索路径,如果"-r"被指定,pathdir将被设为GDB启动时的搜索路径
-environment-pwd 
用法:-environment-pwd
语义:显示当前工作目录
3.线程
-thread-info
尚没实现
-thread-list-all-threads
尚没实现
-thread-list-ids
用法:-thread-list-ids
语义:产生一个GDB当前已知线程的链表
-thread-select
用法:-thread-select threadnum
语义:使threadnum成为当前线程
效果如下:
(gdb)
-thread-list-ids
^done,thread-ids={thread-id="1"},current-thread-id="1",number-of-threads="1"
(gdb)
-thread-select 1
^done,new-thread-id="1",frame={level="0",addr="0x080484f6",func="main",args=[],file="demo.c",fullname="/home/libo/temp/demo.c",line="28"}
(gdb)
4. 程序执行
这些命令都是异步命令
-exec-continue
用法:-exec-continue
语义:继续执行程序,直到有断点或者程序退出
-exec-finish
用法:-exec-finish
语义:将当前函数执行完毕
-exec-interrupt
用法:-exec-interrupt
语义:中止正在执行的程序
-exec-next
用法:-exec-next
语义:执行一行源代码
-exec-next-instruction 
用法:-exec-next-instruction
语义:执行一条机器指令
-exec-return
用法:-exec-return
语义:中止当前函数的执行,立即返回
-exec-run
用法:-exec-run
语义:开始执行程序,直到遇到断点或退出
-exec-step
用法:-exec-step
语义:执行到下一个源代码行,如果此行是函数调用,则停留在调用函数的开始处
-exec-step-instruction
用法:-exec-step-instruction
语义:执行一条机器指令
-exec-until
用法:-exec-until [ location ]
语义:一直执行,直到达到location
效果如下:
-break-insert main
^done,bkpt={number="7",type="breakpoint",disp="keep",enabled="y",addr="0x08048498",func="main",file="demo.c",fullname="/home/libo/temp/demo.c",line="23",times="0",original-location="main"}
(gdb)
-break-insert swap
^done,bkpt={number="8",type="breakpoint",disp="keep",enabled="y",addr="0x0804841b",func="swap",file="demo.c",fullname="/home/libo/temp/demo.c",line="8",times="0",original-location="swap"}
(gdb)
-exec-run
=library-unloaded,id="/lib/ld-linux.so.2",target-name="/lib/ld-linux.so.2",host-name="/lib/ld-linux.so.2"
=library-unloaded,id="/lib/tls/i686/cmov/libc.so.6",target-name="/lib/tls/i686/cmov/libc.so.6",host-name="/lib/tls/i686/cmov/libc.so.6"
=thread-group-created,id="19708"
=thread-created,id="1",group-id="19708"
^running
*running,thread-id="all"
(gdb)
=library-loaded,id="/lib/ld-linux.so.2",target-name="/lib/ld-linux.so.2",host-name="/lib/ld-linux.so.2",symbols-loaded="0"
=library-loaded,id="/lib/tls/i686/cmov/libc.so.6",target-name="/lib/tls/i686/cmov/libc.so.6",host-name="/lib/tls/i686/cmov/libc.so.6",symbols-loaded="0"
*stopped,reason="breakpoint-hit",disp="keep",bkptno="4",frame={addr="0x08048498",func="main",args=[],file="demo.c",fullname="/home/libo/temp/demo.c",line="23"},thread-id="1",stopped-threads="all",core="0"
(gdb)
-exec-continue
^running
*running,thread-id="1"
(gdb)
*stopped,reason="breakpoint-hit",disp="keep",bkptno="3",frame={addr="0x080484f6",func="main",args=[],file="demo.c",fullname="/home/libo/temp/demo.c",line="28"},thread-id="1",stopped-threads="all",core="1"
(gdb)
-exec-continue
^running
*running,thread-id="1"
(gdb)
swap before:0 1 2 3 4 5 6 7 8 9 
*stopped,reason="breakpoint-hit",disp="keep",bkptno="8",frame={addr="0x0804841b",func="swap",args=[{name="a",value="0xbffff254"},{name="len",value="10"}],file="demo.c",fullname="/home/libo/temp/demo.c",line="8"},thread-id="1",stopped-threads="all",core="1"
(gdb)
-exec-next
^running
*running,thread-id="1"
(gdb)
*stopped,reason="end-stepping-range",frame={addr="0x08048424",func="swap",args=[{name="a",value="0xbffff254"},{name="len",value="10"}],file="demo.c",fullname="/home/libo/temp/demo.c",line="10"},thread-id="1",stopped-threads="all",core="1"
(gdb)
-exec-next
^running
*running,thread-id="all"
(gdb)
*stopped,reason="end-stepping-range",frame={addr="0x08048432",func="swap",args=[{name="a",value="0xbffff254"},{name="len",value="10"}],file="demo.c",fullname="/home/libo/temp/demo.c",line="11"},thread-id="1",stopped-threads="all",core="1"
(gdb)
-exec-next-instruction
^running
*running,thread-id="all"
(gdb)
*stopped,reason="end-stepping-range",frame={addr="0x08048435",func="swap",args=[{name="a",value="0xbffff254"},{name="len",value="10"}],file="demo.c",fullname="/home/libo/temp/demo.c",line="11"},thread-id="1",stopped-threads="all",core="1"
(gdb)
-exec-step
^running
*running,thread-id="all"
(gdb)
*stopped,reason="end-stepping-range",frame={addr="0x08048454",func="swap",args=[{name="a",value="0xbffff254"},{name="len",value="10"}],file="demo.c",fullname="/home/libo/temp/demo.c",line="12"},thread-id="1",stopped-threads="all",core="1"
(gdb)
-exec-step-instruction
^running
*running,thread-id="all"
(gdb)
*stopped,reason="end-stepping-range",frame={addr="0x08048457",func="swap",args=[{name="a",value="0xbffff254"},{name="len",value="10"}],file="demo.c",fullname="/home/libo/temp/demo.c",line="12"},thread-id="1",stopped-threads="all",core="1"
(gdb)
-exec-finish
^running
*running,thread-id="all"
(gdb)
*stopped,reason="function-finished",frame={addr="0x08048516",func="main",args=[],file="demo.c",fullname="/home/libo/temp/demo.c",line="32"},gdb-result-var="$1",return-value="0",thread-id="1",stopped-threads="all",core="1"
(gdb)
-exec-step
^running
*running,thread-id="all"
(gdb)
*stopped,reason="end-stepping-range",frame={addr="0x08048523",func="main",args=[],file="demo.c",fullname="/home/libo/temp/demo.c",line="33"},thread-id="1",stopped-threads="all",core="1"
(gdb)
-exec-step             
^running
*running,thread-id="all"
(gdb)
*stopped,reason="end-stepping-range",frame={addr="0x0804852d",func="main",args=[],file="demo.c",fullname="/home/libo/temp/demo.c",line="34"},thread-id="1",stopped-threads="all",core="1"
(gdb)
-exec-step
^running
*running,thread-id="all"
(gdb)
*stopped,reason="end-stepping-range",frame={addr="0x08048546",func="main",args=[],file="demo.c",fullname="/home/libo/temp/demo.c",line="33"},thread-id="1",stopped-threads="all",core="0"
(gdb)
-break-insert 35
^done,bkpt={number="9",type="breakpoint",disp="keep",enabled="y",addr="0x08048552",func="main",file="demo.c",fullname="/home/libo/temp/demo.c",line="35",times="0",original-location="demo.c:35"}
(gdb)
-exec-continue
^running
*running,thread-id="all"
(gdb)
*stopped,reason="breakpoint-hit",disp="keep",bkptno="9",frame={addr="0x08048552",func="main",args=[],file="demo.c",fullname="/home/libo/temp/demo.c",line="35"},thread-id="1",stopped-threads="all",core="0"
(gdb)
-exec-continue
^running
*running,thread-id="1"
(gdb)
swap after:9 8 7 6 5 4 3 2 1 0 
=thread-exited,id="1",group-id="19708"
=thread-group-exited,id="19708"
*stopped,reason="exited-normally"
(gdb)

5. 栈
-stack-info-frame
尚没实现
-stack-info-depth
用法:-stack-info-depth [ max-depth ]
语义:显示栈深度,如果指定了max-depth,超过max-depth的帧不会被计算
-stack-list-arguments
用法:-stack-list-arguments show-values
[ low-frame high-frame ]
语义:显示帧参数,show-values为0只显示参数名称,为1显示名称和值,如果指定了low-frame,high-frame
     则只显示它们之间的参数
-stack-list-frames
用法:-stack-list-frames [ low-frame high-frame ]
语义:列举所有帧,如果指定low-frame和high-frame则只显示它们之间的帧

 

-stack-list-locals

用法:-stack-list-locals print-values
语义:显示当前帧的本地变量,如果print-values为0,只显示变量名称,为1显示名称和值

 

-stack-select-frame

用法:-stack-select-frame framenum

语义:选择framenum帧为当前帧

 

效果如下:

(gdb)
-stack-list-frames
^done,stack=[frame={level="0",addr="0x00401057",func="swap",file="demo.c",line="
12"},frame={level="1",addr="0x0040116f",func="main",file="demo.c",line="34"}]
(gdb)
-stack-info-depth
^done,depth="2"
(gdb)
-stack-list-arguments 1
^done,stack-args=[frame={level="0",args=[{name="a",value="(int *) 0x22eeb0"},{na
me="len",value="10"}]},frame={level="1",args=[]}]

(gdb)
-stack-list-locals 0
^done,locals=[name="i",name="temp"]
(gdb)
-stack-select-frame 1
^done
(gdb)

 

6.变量 

-var-create  

用法:-var-create {name | "-"} {frame-addr | "*"} expression

语义:创建一个变量对象

     name表示变量名,如果指定"-",变量名将被自动创建

     frame-addr表示创建变量所在帧的基址

     expression可以有三种:地址,地址块,寄存器


-var-delete

用法:-var-delete name

语义:删除名为name的变量对象


-var-set-format 

用法:-var-set-format name format-spec

语义:设置名为name的变量的输出格式

     format-spec ==>
{binary | decimal | hexadecimal | octal | natural} 

-var-show-format  

用法:-var-show-format name
语义:查看名为name的变量的输出格式,格式只有上面format-spec指定的几种

 

-var-info-num-children 

用法:-var-info-num-children name

语义:查看名为name的变量的子变量数目

 

-var-list-children 

用法:-var-list-children [print-values] name
语义:查看名为name的变量的子变量,如果print-values为0或者 --no-values则只显示子变量名,

     如果为1或--all-values显示子变量名和值

 

-var-info-type 

用法:-var-info-type name

语义:查看名为name的变量的类型

 

-var-info-expression 

用法:-var-info-expression name
语义:查看名为name的变量的表达式,可返回的表达式语言之有三种:C,C++,JAVA

 

-var-show-attributes 

用法:-var-show-attributes name

语义:查看名为name的变量的属性,属性为{ { editable | noneditable } | TBD }

 

-var-evaluate-expression 

用法:-var-evaluate-expression name

语义:计算名为name的变量的表达式

 

-var-assign 

用法:-var-assign name expression

语义:将一个新的表达式赋给名为name的变量

 

-var-update

用法:-var-update name

语义:更新名为name的变量值,即根据当前的内存或寄存器重新计算变量值

 

效果如下:

(gdb)
-var-create i 1 2
^done,name="i",numchild="0",value="2",type="int",has_more="0"
(gdb)
-var-create - 1 3
^done,name="var1",numchild="0",value="3",type="int",has_more="0"
(gdb)
-var-delete var1
^done,ndeleted="1"
(gdb)
-var-show-format i
^done,format="natural"
(gdb)
-var-list-children 1 i
^done,numchild="0",has_more="0"
(gdb)
-var-info-type i
^done,type="int"
(gdb)
-var-info-expression i
^done,lang="C",exp="2"
(gdb)
-var-show-attributes i
^done,attr="editable"
(gdb)
-var-evaluate-expression i
^done,value="2"

(gdb)
-var-update i
^done,changelist=[{name="i",in_scope="true",type_changed="false"}]
(gdb)

7.数据 

-data-disassemble

用法:-data-disassemble
[ -s start-addr -e end-addr ]
| [ -f filename -l linenum [ -n lines ] ]
-- mode

语义:反汇编某一块内存区,可以按以下两种方式指定内存区:

     1). 指定开始和结束地址,start-addr, end-addr

     2). 指定源文件名和行范围

     mode是显示格式,0显示反汇编代码,1混合显示反汇编和源代码

 

-data-evaluate-expression

用法:-data-evaluate-expression expr
语义:计算表达式expr的值

 

-data-list-changed-registers

用法:-data-list-changed-registers
语义:显示值有变化的寄存器列表

 

-data-list-register-names

用法:-data-list-register-names [ ( regno )+ ]

语义:显示指定了号码的寄存器名字,如果没指定regno,则显示所有的寄存器名字列表

 

-data-list-register-values

用法:-data-list-register-values fmt [ ( regno )*]

语义:显示寄存器的内容,fmt是值的显示格式,如下: 

de> xde> Hexadecimal
de> ode> Octal
de> tde> Binary
de> dde> Decimal
de> rde> Raw
de> Nde> Natural


-data-read-memory


用法: -data-read-memory [ -o byte-offset ]
address word-format word-size
nr-rows nr-cols [ aschar ]


语义:address指定开始地址,byte-offset指定从开始地址的偏移值,


word-format每个字的显示格式,word-size每个字的长度


nr-rows,nr-cols指定输出格式为几行几列



效果如下:


(gdb)
-data-disassemble -s $pc -e "$pc + 20" -- 0
^done,asm_insns=[{address="0x08048498",func-name="main",offset="9",inst="movl $0x0,0x3c(%esp)"},{address="0x080484a0",func-name="main",offset="17",inst="jmp 0x80484b3 <main+36>"},{address="0x080484a2",func-name="main",offset="19",inst="mov 0x3c(%esp),%eax"},{address="0x080484a6",func-name="main",offset="23",inst="mov 0x3c(%esp),%edx"},{address="0x080484aa",func-name="main",offset="27",inst="mov %edx,0x14(%esp,%eax,4)"}]


(gdb)
-data-evaluate-expression &i
^done,value="0x22eeac"


(gdb)
-data-list-register-values x 1 2 3 4
^done,register-values=[{number="1",value="0x0"},{number="2",value="0x4c"},{numbe
r="3",value="0x4"},{number="4",value="0x22ee70"}]
(gdb)
-exec-next
^running
(gdb)
*stopped,reason="end-stepping-range",thread-id="1",frame={addr="0x004010fb",func
="main",args=[],file="demo.c",line="27"}


(gdb)
-data-list-changed-registers
^done,changed-registers=["0","2","8","9"]
(gdb)
-data-read-memory $pc x 2 3 2
^done,addr="0x004010fb",nr-bytes="12",total-bytes="12",next-row="0x004010ff",pre
v-row="0x004010f7",next-page="0x00401107",prev-page="0x004010ef",memory=[{addr="
0x004010fb",data=["0x45c7","0x00c4"]},{addr="0x004010ff",data=["0x0000","0x8300"
]},{addr="0x00401103",data=["0xc47d","0x7f09"]}]
(gdb)



以后的8、9等命令GDB大部分尚没实现,或很少使用,不再解释。



不同的GDB版本极少数命令可能稍有差异,可自己查看GDB手册或命令行提示。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多