文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>GDB/MI 层命令介绍

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.其它杂项

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

 

/**//*
** 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表示只读时有效
运行效果:
(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手册或命令行提示。

 

本篇文章至此结束。

排行榜 更多 +
2399玩游盒

2399玩游盒

游戏工具 下载
棘龙模拟器

棘龙模拟器

音乐节奏 下载
老铁救救这只羊

老铁救救这只羊

休闲益智 下载