GDB/MI 层命令介绍
时间:2007-04-04 来源:loughsky
//作者:coutcin,http://blog.csdn.net/coutcin
对于gdb的命令很多人可能都已经很熟悉了,本文介绍的mi层命令可能很少有人用到,它也是gdb的一部分,主要目的是为一些目标系统如IDE等提供调试功能,如eclipse下c/c++的cdt插件的底层就是调用的mi层命令,cdt的包里面有两个类RxThread,TxThread就是一个发送mi命令,一个接收返回数据的,大家有兴趣可以研究下。
mi的命令依然是以文本行方式提供的,并兼容我们常用的gdb CLI命令,下面我们看一下它的进入和退出:
⇒进入命令 gdb --interpreter mi ****.exe
⇒推出命令 quit
效果如下:
D:\exercise\c\test>gdb --interpreter mi
~"GNU gdb 6.3.50_2004-12-28-cvs (cygwin-special)\n"
~"Copyright 2004 Free Software Foundation, Inc.\n"
~"GDB is free software, covered by the GNU General Public License, and you are\n
"
~"welcome to change it and/or distribute copies of it under certain conditions.\
n"
~"Type \"show copying\" to see the conditions.\n"
~"There is absolutely no warranty for GDB. Type \"show warranty\" for details.\
n"
~"This GDB was configured as \"i686-pc-cygwin\"."
~"\n"
(gdb)
quit
&"quit\n"
D:\exercise\c\test>
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.其它杂项
我们以下面这段代码为例演示各种命令的执行结果:
















































执行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表示只读时有效
运行效果:
(gdb)
-break-insert main
^done,bkpt={number="1",type="breakpoint",disp="keep",enabled="y",addr="0x004010f
6",func="main",file="demo.c",line="23",times="0"}
(gdb)
-break-insert 28
^done,bkpt={number="2",type="breakpoint",disp="keep",enabled="y",addr="0x0040110
8",func="main",file="demo.c",line="28",times="0"}
(gdb)
-break-list
^done,BreakpointTable={nr_rows="2",nr_cols="6",hdr=[{width="3",alignment="-1",co
l_name="number",colhdr="Num"},{width="14",alignment="-1",col_name="type",colhdr=
"Type"},{width="4",alignment="-1",col_name="disp",colhdr="Disp"},{width="3",alig
nment="-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="0x0040
10f6",func="main",file="demo.c",line="23",times="0"},bkpt={number="2",type="brea
kpoint",disp="keep",enabled="y",addr="0x00401108",func="main",file="demo.c",line
="28",times="0"}]}
(gdb)
-exec-run
^running
(gdb)
*stopped,reason="breakpoint-hit",bkptno="1",thread-id="1",frame={addr="0x004010f
6",func="main",args=[],file="demo.c",line="23"}
(gdb)
-exec-continue
^running
(gdb)
*stopped,reason="breakpoint-hit",bkptno="2",thread-id="1",frame={addr="0x0040110
8",func="main",args=[],file="demo.c",line="28"}
(gdb)
-break-delete 1
^done
(gdb)
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="3",thread-id="1"},number-of-threads="2"
(gdb)
-thread-select 1
^done,new-thread-id="1",frame={level="0",func="main",args=[],file="demo.c",line=
"27"},line="27",file="demo.c"
(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
效果如下:
(gdb)
-break-insert main
^done,bkpt={number="4",type="breakpoint",disp="keep",enabled="y",addr="0x004010f
6",func="main",file="demo.c",line="23",times="0"}
(gdb)
-break-insert swap
^done,bkpt={number="5",type="breakpoint",disp="keep",enabled="y",addr="0x0040105
7",func="swap",file="demo.c",line="12",times="0"}
(gdb)
-exec-run
^running
(gdb)
---Type <return> to continue, or q <return> to quit---
*stopped,reason="breakpoint-hit",bkptno="4",thread-id="1",frame={addr="0x004010f
6",func="main",args=[],file="demo.c",line="23"}
(gdb)
-exec-continue
^running
(gdb)
swap before:0 1 2 3 4 5 6 7 89
*stopped,reason="breakpoint-hit",bkptno="5",thread-id="1",frame={addr="0x0040105
7",func="swap",args=[{name="a",value="0x22eeb0"},{name="len",value="10"}],file="
demo.c",line="12"}
(gdb)
-exec-next
^running
(gdb)
*stopped,reason="end-stepping-range",thread-id="1",frame={addr="0x00401073",func
="swap",args=[{name="a",value="0x22eeb0"},{name="len",value="10"}],file="demo.c"
,line="14"}
(gdb)
-exec-next-instruction
^running
(gdb)
*stopped,reason="end-stepping-range",thread-id="1",frame={addr="0x00401076",func
="swap",args=[{name="a",value="0x22eeb0"},{name="len",value="10"}],file="demo.c"
,line="14"}
(gdb)
-exec-step
^running
(gdb)
*stopped,reason="end-stepping-range",thread-id="1",frame={addr="0x00401086",func
="swap",args=[{name="a",value="0x22eeb0"},{name="len",value="10"}],file="demo.c"
,line="15"}
(gdb)
-exec-step-instruction
^running
(gdb)
*stopped,reason="end-stepping-range",thread-id="1",frame={addr="0x00401089",func
="swap",args=[{name="a",value="0x22eeb0"},{name="len",value="10"}],file="demo.c"
,line="15"}
(gdb)
-exec-return
^done,frame={level="0",addr="0x0040116f",func="main",args=[],file="demo.c",line=
"36"}
(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",type="int"
(gdb)
-var-create - 1 3
^done,name="var2",numchild="0",type="int"
(gdb)
-var-delete var2
^done,ndeleted="1"
(gdb)
-var-show-format i
^done,format="natural"
(gdb)
-var-list-children 1 i
^done,numchild="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是值的显示格式,如下:
x Hexadecimal o Octal t Binary d Decimal r Raw N Natural
►-data-read-memory
用法: -data-read-memory [ -o byte-offset ]address word-format word-sizenr-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="0x004010f6",func-name="main",offset="37",inst="call
0x401250 <__main>"},{address="0x004010fb",func-name="main",offset="42",inst="mo
vl $0x0,0xffffffc4(%ebp)"},{address="0x00401102",func-name="main",offset="49",
inst="cmpl $0x9,0xffffffc4(%ebp)"},{address="0x00401106",func-name="main",offs
et="53",inst="jg 0x401119 <main+72>"},{address="0x00401108",func-name="main"
,offset="55",inst="mov 0xffffffc4(%ebp),%edx"}]
(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手册或命令行提示。
本篇文章至此结束。