对于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 mimi的命令总共分为以下几个部分:
1.断点(Breakpoint)
2.程序环境(Program Context)
3.线程(Thread)
4.程序执行(Program Execution)
5.栈(Stack)
6.变量(Variable)
7.数据(Da
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表示只读时有效
运行效果:
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
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)(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"
-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-addr2). 指定源文件名和行范围mode是显示格式,0显示反汇编代码,1混合显示反汇编和源代码-data-evaluate-expr ession 用法:-data-evaluate-expr ession 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是值的显示格式,如下:
-da
用法: -da
address word-format word-size
nr-rows nr-cols [ aschar ]
语义:address指定开始地址,byte-offset指定从开始地址的偏移值,
word-format每个字的显示格式,word-size每个字的长度
nr-rows,nr-cols指定输出格式为几行几列
效果如下:
(gdb)
-da
^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)
-da
^done,value="0x22eeac"
(gdb)
-da
^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)
-da
^done,changed-registers=["0","2","8","9"]
(gdb)
-da
^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",da
]},{addr="0x00401103",da
(gdb)
以后的8、9等命令GDB大部分尚没实现,或很少使用,不再解释。
不同的GDB版本极少数命令可能稍有差异,可自己查看GDB手册或命令行提示。
联系客服