c :十进制数+字符,仅仅显示一个字符的信息,43 '+'
f :浮点格式显示,5.88542412e-039
s :字符串显示,不适用于print,因为有些字符打印不出来
r :以上一次的格式显示
----------------------------------------------------------------------------------------------------------------------------------
9. GDB中的表达式expr。GDB中许多的指令(例如:print,display等)都会将表达式(expr)作为参数并计算该expr的值,任何类型的常量、变量、你所使用
的编程语言支持的运算符都可以作为expr中的元素,这包含:条件表达式、四则运算、函数调用、数据类型强制转换、字符串常量、甚至预处理器宏。
并且,在GDB中允许将同种类型的变量作为一个array一次输入,格式为{elem1,elem2,elem3,...},这可以用在disp/print中时将多个变量打包显示。
下面是GDB支持的C语言之外的运算符(10.1 Expressions),
@ :是一个二元运算符,它将部分内存看做一个数组,多用于构建人工数组(artificial array)。格式为ST@LEN,其中ST表示数
组的起端,LEN表示长度。根据ST的类型不同,情况如下:
1)ST为一个地址/指针时,则可以使用 *ST@len 显示从地址ST开始的len个元素,比如arr为一个数组名,则*arr@3就是显示数组
的前3个元素,而arr@3则是将数组看做一个元素,连续显示三个数组的值。
2)ST为一个基本数据类型的变量名,ST@len 等价于*(&ST)@len
3)ST是一个结构体名时,则可用于显示结构体数组。ST@len表示{ST[0],ST[1],...,ST[len-1]}
:: :变量的引用,主要形式为 file::variable
function::variable
{type} addr :类型强制转换
Note1:关于人工数组(artificial array)。调试的过程中,连续打印输出内存中的某种数据类型的对象(变量、数组、结构体等)是非常有用的,
比如,数组的一部分和仅有指针的动态数组的显示,都需要将一块连续内存的数据输出,此时就可以在GDB中使用人工数组。人工数组的构建
有两种方式,一种就是上面的 ST@LEN。另一种方法是使用类型强制转换(cast),这种方式常用于将一个位数多的基本类型数据转换为几个
位数少的基本类型的数据,比如(GDB指令):(10.4 Artifi cial Arrays)
p/x (short[])0x12345678 ----> {0x5678, 0x1234}
p/x (char[])0x12345678 ----> {0x78, 0x56, 0x34, 0x12}
可以看到,它实际上是将一个位数多的基本类型看做一个位数少的基本类型的数组。
可以将多个同类型的变量构成一个人工数组{var1,var2,......}
Note2:人工数组只能用于处理内存中连续的数据,而对非连续数据(比如结构体数组中每个元素的某个成员)无能为力,此时可以使用在GDB中使用
set定义自由变量(convenience variable)实现。(10.11 Convenience Variables)
struct my_struct
{
int id;
char name[20];
int age;
score my_score;
} st_arr[]={...};
比如上面的结构体数组,如果想要输出这20个数组元素(结构体)的name,则可以如下操作(GDB指令,RET表示键盘的回车键),
set $i = 0
print/u st_arr[i++].id
RET
RET
.....
RET
Note3:关于自由变量的详细说明。自由变量以"$"开头,以set进行赋值,例如:set $foo = *object_ptr 就是将指针object_ptr指向的值保存到
GDB中的自由变量$foo中。自由变量是泛型变量,可以随时改变其类型。
两个指令:
show convenience/conv :列出到目前为止所有已经定义的自由变量及其当前值;
init-if-undefined $variable = expr :类似于makedile中的variable ?= expr,或者C语言中带初始化的局部变量。常用于用
户自定义指令时设定初始状态。
自由变量最常见的用途已在Note2中给出。GDB启动时预定义了一些自由变量如下,
$_ :保存着内存检测(10.6 Examining data)指令x最后检测的内存地址,其它为x指令提供初始/默认地址的指令
(比如info line linenum 和 info breakpoint)都会改变$_的值。info line linenum会将$_设定为源文件中
第linenum行对应的第一条汇编指令的地址;info breakpoint会将$_设定为最后一个breakpoints类型断点的地
址。在不做显式复制的情况下,$_的类型默认为 void *,可以使用 whatis $_指令查看。
$__ :保存着x指令访问内存的最后一个单元的值,其类型由x/nfu中的u决定。下面为一个$_和$__的例子,
break main # 在main函数入口处设断点,假设其为第一个断点(即断点号为1),断点地址为 0x401568
info break 1 # 会显示1号断点的信息,并且GDB暗中会执行:set $_ = 0x00401568,set $__ = *0x401568
print/x $_ ---> 0x401568
x/1xh 0x401568 # 将$__输出格式改为int16
Print/x $__ ---> 0x8b10
whatis $_ ---> type = void *
whtais $__ ---> type = int16_t
$_exitcode :保存着程序结束调试时的 exit code
$_sdata :contains extra collected static tracepoint data
$_siginfo :contains extra signal information
$_tlb :保存着线程信息块的地址,下面例子中可以看到线程号保存在[0x7efdd020,...0x7efdd028]中。
x/10xg $_tlb
0x7efdd000: 0x002900000028ffc4 0x000000000028e000
0x7efdd010: 0x0000000000001e00 0x000000007efdd000
0x7efdd020: 0x0000ec340000ec3c 0x00827ed000000000
0x7efdd030: 0x000000007efde000 0x0000000000000000
0x7efdd040: 0x0000000000000000 0x0000000000000000
info program
Using the running image of child Thread 60476.0xec34.
Program stopped at 0x401664.
It stopped at breakpoint 5.
Type "info stack" or "info registers" for more information.
----------------------------------------------------------------------------------------------------------------------------------
10. 当前文件内的搜索。
search/forward-search regexp :从上次list的最后一行向后搜索到第一个满足正则表达式regexp的行,并显示;
reverse-search regexp :从上次list的最后一行向前搜索到第一个满足正则表达式regexp的行,并显示;
----------------------------------------------------------------------------------------------------------------------------------
11. 程序当前执行位置的获取和修改,包括PC值、当前在源程序中的位置(文件名+行号)
1)获取当前PC值的方式:>print $pc
<$8 = (void (*)()) 0x40162b
2)获取当前PC值的修改:>print $pc=0x40162F
<$9 = (void (*)()) 0x40162f
3)只显示pc值:print/x $pc
4)pc处的汇编指令和内存地址同时给出:x/i $pc, 或者disp/i $pc,两者等价
5)当前pc在源程序中对应的行号,bt指令、f指令,或者先获取$pc的地址值,然后使用info line *addr($pc的值)
----------------------------------------------------------------------------------------------------------------------------------
12. 检查数据(10 Examining Data)
1)最常用的检查你的程序中数据的方式是使用print/p指令或者inspect指令,两者是完全等价的。
print [expr] :如果不给出expr,则会重复上一条print指令。
print /f [expr] :f为第8小节中给出的格式,关于expr参见第9小节。如果不给出f,则会以expr本身的类型决定显示格式。
2)修改变量的值。print或者set指令,两者的区别在于print会回显并将,而set不回显。如果该变量与gdb中的指令相混,则使用set variable/var指令设置变量的值。
比如,gdb有专用的set width指令,而如果你的原程序中有个变量为width,则设置其值时使用set variable/var width=111。所以一般使用set var。
3)修改内存的值,set {int}0x83040 = 4为将内存地址0x83040处的一块int类型的区域设置为4。
4)使用一小节的x指令显示内存的值
----------------------------------------------------------------------------------------------------------------------------------
13. 检查符号表常用指令(16 Examining the Symbol Table)
1)whatis [var]指令和ptype expr指令用于显示一个变量的类型,前者仅给出类型名,后者会给出结构体的具体结构。对于多层的typedef,
两者只显示当前层的类型名。(16 Examining the Symbol Table)
(gdb) whatis st1 -----> type = struct my_struct [4]
(gdb) ptype st_arr ----->
type = struct my_struct {
int id;
char name[20];
int age;
score my_score;
} [4]
2)info scope location,这里的location可以参见上面第7小节。
3)info source:显示当前pc值所在源文件的信息,
(gdb) info source ----->
Current source file is main.c # 文件名
Compilation directory is E:\AGM\winIDE_gcc_gdb\PrjEx_Console # 路径
Located in E:\AGM\winIDE_gcc_gdb\PrjEx_Console\main.c # 当前pc值所在的源文件名,绝对路径
Contains 101 lines. # 该源文件的行数,(如果包含多个空行,则为总行数-1)
Source language is c. # 源文件的类型
Compiled with DWARF 2 debugging format. # 调试信息的模式
Does not include preprocessor macro info. # 是否包含预处理宏
4)info sources:列出你的程序中所有涉及到的有调试信息的源文件名,分成两部分:符号表已经被读入的部分和将要读入的部分。
5)info types [regexp]:列出你的程序中涉及到的所有类型(不提供 regexp 选项时)或者满足正则表达式 regexp 的类型。
6)info functions [regexp]:列出你的程序中涉及到的所有函数(不提供 regexp 选项时)或满足正则表达式 regexp 的函数。对于有调试信息的
函数会给出其声明原型,没有调试信息的只给出函数名。
7)info variables [regexp]:列出你的程序中所有在函数外部定义的变量(不提供 regexp 选项时)或满足正则表达式 regexp 的所有函数外部定义
的变量。通过分析汇编代码可知,链接脚本文件中定义的变量也被包含在内。
8)info symbol addr:查询地址内存 addr 处的符号名,如果此地址处没有符号则打印出距离最近的符号及偏移量。例如,info symbol 00401010。
9)info address symbol:查询符号 symbol 的数据所存放的内存地址,例如,info address main。
----------------------------------------------------------------------------------------------------------------------------------
14. 输出格式的控制(10.8 Print Settings)
1)输出符号地址(print/display 的expr为地址)时是否给出在那个文件的哪一行。
show print symbol-filename # 显示是否开启了
set print symbol-filename on/off # 开启或者关闭,默认是关闭的
下面是一个打印输出当前$pc值的例子,即print $pc
关闭时:(void (*)()) 0x401664
开启时:(void (*)()) 0x401664
但是,当附加/nfu参数之后,就不起作用了。
2)数组显示格式的调整
set print repeats num :表示连续有超过num个数组元素相同时,使用"
show print repeats :当前的num是多少。
set print array on/off :是否列显示数组,on为列显示,off为行显示(默认)。
show print array :当前是行还是列显示。
set print array-indexes on/off:是否显示数组的下标(默认off不显示)。
show print array-indexes :当前的数组下标设置是什么。
set print elements number-of-elements :设置GDB中一次能够显示的数组的元素数,0/unlimited时无限制。
show print elements :当前GDB一次能显示多少个元素。
set print null-stop on/off :设置字符串数组显示时是否碰只输出到null(默认全输出)。
show print null-stop :当前的null-stop设置
3)结构体显示格式都得调整
set print pretty on/off :on为以结构树方式显示,off为行显示(默认为off)
show print pretty :当前的结构体显示方式
4)联合体的显示
set print union on/off :on显示出联合体,off以{...}表示联合体防的值
show print union :当前设置
----------------------------------------------------------------------------------------------------------------------------------
15. 自由函数(10.12 Convenience Functions)
1) $_isvoid(expr) :如果expr为void则返回1,否则返回0。可以用于检测一个自由变量是否已经定义并赋值。也可以用于检测一个函数的返回值类型。
2) $_memeq(buf1, buf2, length):比较地址buf1和buf2处的长度为length的内存值是否相等,相等为1。
3) $_regex(str, regex) :如果字符串str符合正则表达式regex,则返回1。
4) $_streq(str1, str2) :字符串str1与str2比较,相等返回1。
5) $_strlen(str) :字符串str的长度。
可以使用指令help function列出所有自由函数
----------------------------------------------------------------------------------------------------------------------------------
16. 寄存器(10.13 Registers)
不同的构架的处理器,其内部的寄存器数量和名称各不相同,GDB中给出了4个通用的寄存器:$pc,$sp,$fp,$ps。要查看当前处理器上的寄存器,可使用一下指令
info registers :查看基本寄存器的值(除了浮点寄存器和向量寄存器之外的寄存器)
info all-registers :所有寄存器
info registers regname... :指定寄存器的名字,查看其当前信息,这里的名字前面可以没有$
info float :查看浮点数硬件的信息(x86下为16个寄存器),只适用于有FPU的处理器。
info vector :查看vector寄存器(mm0 ~ mm7,xmm0 ~ xmm7)的信息,也就是与MMX指令和SSE指令相关的寄存器
----------------------------------------------------------------------------------------------------------------------------------
17. 内存和文件之间的复制(10.17 Copy Between Memory and a File)
dump [format] memory filename start_addr end_addr :将内存[start_addr,end_addr]中的值输出到文件filename。
dump [format] value filename expr :将表达式expr的值输出到文件filename,格式可以是binary,ihex,srec,tekhex。
append [binary] memory filename start_addr end_addr
append [binary] value filename expr :将相应的内存或表达式的值追加到指定的指定的问价(只能是binary类型)
restore filename [binary] bias start end :将filename的内容加载到内存。对于binary的文件,必须指明binary选项,其他类型的不需要指明类型。
如果bias非0,则将bias加到filename中的内容地址中(比如hex文件)。这里的意思是,假设一个hex
文件内部的地址是[A,B](其中,A<=start, B>=end),则需要将该hex文件[start,end]地址之间的内容
加载到内存的[start+bias,end+bias]处。
----------------------------------------------------------------------------------------------------------------------------------
18. GDB的帮助系统
1) help,列出所有指令的分类,包括别名(aliases)、断点(breakpoints)、数据(data)、文件(files)、内部(internals)、隐含(obscure)、运行(running)、栈(stack)、
状态(status)、支持(support)、跟踪点(tracepoints)和用户自定义(user-defined)这几类。
2) help all,会详细列出所有分类的详细指令。
3) help class,会详细列出class类别指令中的所有指令。
4) help cmd,列出指令cmd的说明,如果cmd后面还有子指令,则会全部列出,并简要说明其使用。例如,help info和help info frame。
5) apropos args,会在GDB的所有指令中搜寻args的匹配项,并全部列出。其中,args可以是正则表达式。
6) complete args,GDB会列出所有以args开始的指令,一般只会列到第一层指令,也就是说如果使用complete info,则只会列出info,而不会列出info的子指令。
7) info,获取正在调试的程序的相关信息,通过输入info或者help info可以查看到所有的info子指令,利用这些子指令就能查看当前程序的各种信息。
8) show,用于获取当前GDB程序本身的各种设置,使用help show可以显示show的各种子指令,如果单独使用show指令,则等于一次运行了所有的show子指令,会把GDB
的所有设置一次全列出来。
9) set,可用于设置环境变量、自由变量、show里面的设置。
Note:要产生带预编译宏信息,并能将其展开的可GDB调式的程序,在编译时需要使用-g3或者-ggdb3等级的debugging选项。
也就是说,如果是将宏添加到查看,则需要编译时使用-g3或者-ggdb3等级的debugging选项。
----------------------------------------------------------------------------------------------------------------------------------
19. 检查堆栈(8 Examining the Stack)
1) bt [n],显示堆栈的回溯结构,主要就是说各个堆栈中最后执行的一条语句对应源文件中的行号。比如,
#0 list_add (new=0x6c1878, head=0x28fee4) at StdList.h:61
#1 0x00401801 in main () at main.c:82
pc指针当前所在的堆栈为#0号堆栈,以此类推,main/winmain函数所在的堆栈为最外层堆栈。
如果加n参数,则只显示n个堆栈,n>0时,会显示最内层的n个堆栈的回溯结构,n<0时,显示最外层的n个堆栈的回溯结构。
2) bt full [n],在1)的基础上,还会显示各层堆栈的局部变量。可以调用它来实时显示整个系统的所有局部变量。n的含义如上。
3) 几个设置堆栈回溯结构显示时的指令如下(C语言),
a) set backtrace past-main on/off,是否到了main层后还继续回溯,默认为off,即到main结束。
show backtrace past-main, 显示当前的 past-main设置。
b) set backtrace past-entry on/off,是否到了程序的入口函数(linker设置的入口函数)之后还进一步回溯。默认off。
show backtrace past-entry, 显示past-entry的当前设置。
c) set backtrace limit n/0,设置堆栈回溯的最大层数为n,0表示无限层(默认)。
show backtrace limit, 当前的层数设置
d) set filename-display relative/basename/absolute,堆栈回溯结构中文件名是否带绝对路径
show filename-display,当前的文件名路径设置
4) frame/f [n],选择n号堆栈,当前层位0号,不给出n等价于f 0。并显示当前选择的堆栈的基本信息,包含跳转/pc处对应的源文件信息。
up [n] ,选择从当前堆栈向上n层的堆栈,如果没有n参数,则等价于up 1。并显示当前选择的堆栈的基本信息,。。。
down [n] ,选择从当前堆栈向下n层的堆栈,如果没有n参数,则等价于down 1。并显示当前选择的堆栈的基本信息,。。。
up-silently [n] ,与up功能相同,但不会显示任何信息。
down-silently [n] ,与down功能相同,但不会显示任何信息。
5) info f,显示当前选择的堆栈的详细信息,包括:堆栈号、堆栈地址、上一层的堆栈地址、传递的参数地址、局部变量的地址、上一层的sp,
保存的ebp和eip等
6) info args 上一层传递过来的函数参数的信息
7) info locals,本层的局部变量
Note1:bt指令还有两个别名指令,where和info stack。
Note2:可以有两种方法查看各层堆栈的局部变量,
m1) 直接使用bt full,则依次把各层的局部变量都显示出来
m2) 配合使用 f n和info locals两条指令,用f n跳转到某层堆栈,再用info locals查看哪一层的局部变量,不要忘记查看完了之后,
使用 f 0跳转回当前层。
----------------------------------------------------------------------------------------------------------------------------------
20. gdb的主要启动选项(2 Getting In and Out of gdb)
这里的选项是指启动gdb时,在gdb.exe/gdb32.exe后面加的选项(选项为全拼时前面为"-"和"--"一样,但简写时必须为"-",这里只在silent处
说明,后面相同)。
调用gdb的格式为,gdb32.exe [options] [file.exe],如果不给出file.exe,则可以在进入gdb之后使用file file.exe导入。
--silent或-silent:进入GDB时不打印版权信息。
-command或者-x file:执行file文件中的gdb指令,可以通过在这个文件使用source cmdfile指令再导入其它一些指令文件,而每一个cmdfile文件
都做一些不同的设置,从而达到对GDB环境的不同配置。然后再通过file file.exe载入要调试的程序,并导入断点信息,
这是一种实现方案。
-init-command或者-ix file:执行file中的gdb指令,与-x指令不同的是,这种指令引入的文件只能在载入符号表之前起作用,所以其中不能存在
file file.exe这种指令。也就是说,gdb启动时会先执行-ix后面的文件,然后再执行-x后面的文件。
-nx或者-n:不自动执行所有的三个目录下的.gdbinit文件,实际上从GDB 7.5版本之后,默认已经不执行这些文件了,所以该选项没什么用,但是
不给出该选项的话,启动的时候会给出提示一堆提示消息说路径下有.gdbinit,但为了安全期间,没有给你导入。
-annotate level:level为0-3的整数,默认为0,dev-cpp使用的level=3,C-free使用的0,Emacs使用的1。区别在于提示符机制不同。
-interpreter或者-i interp:选择GDB使用的解释器系统,interp的值可以为:
1) console,传统的命令行(默认)
2) mi,gdb/mi接口,等价于mi2。推荐用于将GDB作为调试后台的GUI或者IDE。
3) mi2,最新的mi
4) mi1,GDB 5版本中的mi
-write:打开可执行文件的可写特性,相当于set write on
-statistics:
Note1:GDB中调用shell指令的方式,
1) shell cmd-string
2) ! cmd-string
Note2:启动GDB最好使用-nx --silent选项
----------------------------------------------------------------------------------------------------------------------------------
21. 程序的反向执行(6 Running programs backward),暂时不支持windows平台。
在目标环境支持的情况下,GDB允许你反向执行程序,回到前一个状态。支持反向执行的目标环境应当能够撤销返回点与当前点之间在机器状态上做出
的改变(例如,变量、寄存器等能返回到之前的状态)。所以并不是所有目标环境都能支持该功能。GDB支持的下面的反向执行指令,
reverse-continue/rc [ignore-count] :反向继续执行直到遇到断点,ignore-count如前面continue指令一样。
reverse-step [count] :反向的step指令,count为行数。
reverse-stepi [count] :反向执行1/count条汇编指令。这里要注意的是,反向执行的汇编指令是pc上面的那条指令,而不是pc指向的
指令。
reverse-next [count] :反向的next指令,count为行数。
reverse-nexti [count] :反向执行的nexti。
reverse-finish :回到当前函数的入口处。
set exec-direction reverse :设置所有的指令都反向执行,影响到的指令包括step, stepi, next, nexti, continue和finish。
set exec-direction forward :设置所有的指令都正向执行,这是GDB的默认设置。
show exec-direction :显示当前GDB的指令执行方向。
Note:GDB反向调试的方法有两个,一个是直接调用相应的reverse-*指令,另一个是设置exec-direction。
----------------------------------------------------------------------------------------------------------------------------------
22. C语言的预编译宏(12 C Preprocessor Macros)的主要指令
macro expand expression:将宏表达式macro_expr展开,macro_expr必须是完整的表达式
info macro macro_expr :显示宏macro_expr的信息,对于函数宏只需要给出名字即可
info macro linespec :显示在linespec行起作用的所有宏
Note:这里编译时需要使用-ggdb3或者-gdwarf-2 -g3选项
----------------------------------------------------------------------------------------------------------------------------------
23. 调试时修改原程序(17.6 Patching Programs)
set write on/off 开启或者关闭原程序修改功能,默认关闭
show write 当前是否开启
----------------------------------------------------------------------------------------------------------------------------------
24. 对于GDB的扩展,主要探讨指令序列的打包方式(Canned Sequences of Commands)、使用Python扩展GDB的方式、如何利用alias简化指令。
GDB提供了一些扩展机制。调试时,GDB能够读取一个脚本文件并根据其后缀启用不同的扩展语言对其进行解释执行,对于不能识别后缀的脚本文件,
统一作为GDB指令文件处理。
set script-extension off/soft/strict:对于脚本文件的处理方式设定,off表示所有脚本文件都作为GDB指令处理;soft表示根据后缀名决定处
理方式,不能识别的作为GDB指令文件处理(默认);strict也是按够追名处理,但不能识别的会报错。
show script-extension :当前的脚本文件处理方式。
1)除了可以在断点处定义指令序列外,GDB还提供了两种方式来将指令序列作为一个单元执行:用户自定义指令、指令文件,下面分别介绍。
a)用户自定义指令,是指将一个指令序列起一个名字作为一个指令对待,该自定义指令可以接受10个输入变量:$arg0...$arg9(类似于批处
理和shell脚本中的参数),具体的输入变量个数可以通过变量$argc获得。例如,
define adder
if $argc == 2
print $arg0 + $arg1
end
if $argc == 3
print $arg0 + $arg1 + $arg2
end
end
则执行,adder 1 2 3就会输出6。
define cmd_name :定义一个名为cmd_name的自定义指令,格式如上面例子。重定义时gdb会询问是否更改->->query。
document cmd_name :将已定义的指令cmd_name加入到帮助中,使得使用help能查询到。格式跟define一样,也是以end结束。重定义不询问。
dont-repeat :用在自定义指令中,告诉gdb当RET时不重复执行该自定义指令,最好作为第一条指令。
help user-defined :会列出所有用户自定义指令和所有COMAND_USER类中定义的python指令。
show user [cmd_name] :显示所有自定义指令或仅仅cmd_name指令使用到的gdb指令,也就是列出包含的指令序列。
Note1:这里的输入变量编号与shell或者批处理有区别,批处理或shell中,文件名本身是$0或%0,而这里自定义指令名本身不占用变量。
Note2:这里的参数是文本替换(类似宏替换),所以参数可以是变量、表达式、甚至是函数调用。
b)指令文件,是由GDB指令序列构成的文件,#开始的行为注释,空行不起作用(跟terminal时交互不同)。指令文件是通过source指令导入执行的,
跟第2小节“4)断点存到文件和从文件读取”格式相同,本质上都是执行一个文件中的指令。指令文件中可以包含a)中的用户自定义指令,而且最
好能将自定义指令单独写到一个指令文件,在启动gdb的时候导入。再将source的格式说明如下,
source [-s] [-v] filename :filename为指令文件
-s选项,当前路径下没有,会到path路径搜索。作用不大,完全可以不用。
-v选项,显示每条指令和它们的执行情况。在指令完全正确的情况下,建议不使用该选项。
当执行source指令时,会先在当前目录下搜索filename,如果找不到则到directory指令指定的目录下寻找。不指定-v选项时,则个指令执行时,
不会再terminal下面显示该指令,若给出-v选项,则会显示每条指令和它们的执行情况。
c)无论是用户自定义指令还是指令文件,都可以使用流程控制指令(flow-control commands)处理一些复杂情况。
_______________________________________________
| if
| cmd_1 | cmd_1 |
| cmd_2 | cmd_2 |
| ...... | ...... |
| cmd_n | [loop_break] |
| [else | [loop_continue]|
| cmd_11 | ...... |
| cmd_12 | cmd_n |
| ...... | end |
| cmd_1n] | |
| end | |
-----------------------------------------------
2)用户自定义指令和指令文件中,GDB的输出被禁用了,唯一的输出是print、x类型的指令定义的输出。这里有几个用于输出信息的其它指令。
a)echo text :text为要打印的内容,支持转义字符("\n"表示换行,"\ "表示空格,行尾的"\"表示续行)
b)output[/fmt] expr :跟print类似,当不会出现print时的"$n = "部分。expr的说明参见第9小节,fmt参见第1和第8小节。
c)printf template, expressions... :等同于C语言中的"printf (template, expressions...);"。
d)eval template, expressions... :暂时没看懂怎么用
----------------------------------------------------------------------------------------------------------------------------------
25. gdb中的文件(18 gdb Files)
指定文件操作指令
1)file [filename] :从 filename 中读取符号表和可执行文件,当不指定 filename 时则指舍弃之前的符号表和可执行文件。
2)exec-file [ filename ] :从 filename 读取可执行文件。
3)symbol-file [ filename ]:从 filename 读取符号表。
4)info target/files :打印出当前调试对象的进程+线程号、入口点、可执行程序的完整内存分配情况(包括各个dll文件的段的地址分配)。
run之前不包含dll信息,run之后才会包含相应的dll信息。
5)maint info sections:打印出目标映像文件的内存映像及属性。
6)info sharedlibrary/share/dll [regex]:打印出所调试程序所加载的所有dll或者与正则表达式regex匹配的dll的内存分配情况,逆向工具
中大多会给出这些信息。
----------------------------------------------------------------------------------------------------------------------------------
26. GDB/MI接口(27 The gdb/mi Interface)
所有的GDB/MI输入指令前面都可以加一个区分其输出的token,token是一个纯数字组成的序列。
1)GDB/MI是一种基于命令行与GDB进行文本交互的解释器,可又通过两种方式实现GDB/MI形式的GDB:
a)启动GDB时添加选项, --interpreter | -i mi
b)在GDB/console模式下,执行interpreter-exec mi "cmd"
C)在GDB/MI模式下,如果要执行GDB/console指令,也有两种方式:直接输入GDB/console指令,
或者-interpreter-exec console "GDB/console指令",推荐采用后者。
2)对使用到的符号和术语做以下设定:
a) | 用于分隔可选项
b) [ something ] 表示something是可选的,指令中可以/能有也可以/能没有
c) ( group )* 表示至少有0个group,group可以是选项(对于输入),也可以是各种类型的输出(对于输出)
d) ( group )+ 表示至少有1个group,group含义如上
e) "string" 表示字符串字面量
3)前端程序与GDB的交互包含3个要素:前端发给GDB的指令、GDB对这些指令的响应(response)、GDB给前端的一些通知/提示(notification)。
一条指令会产生一个响应(标识指令是否执行成功):对于查询,响应包含要查询的信息,对于执行或设置类指令,响应会返回是否成功的信息。
Notification是一种将GDB状态或/和目标设备状态的变化进行汇总并汇报给前端程序的机制(是一种异步输出信息)。4种主要的Notification如下:
a)Exec notifications:反映目标设备状态的改变(开始、停止、继续等),这种信息一般以"*"作为前缀;
b)Status notifications:反映长时间运行的操作的过程,一般以"+"作为前缀(测试中没发现这种信息,故仍不知其具体含义);
c)General notifications:反映GDB的指令可能对GDB或者目标设备的状态产生的一些未知改变(比如resume程序之后会改变堆栈状态、断点表发生
改变等),一般以"="作为前缀;
d)Console output notifications:命令行指令的文本响应,通常以"~"作为前缀。
4)运行环境管理,
a)线程和堆栈管理,某些GDB/MI指令需要显式指定它所操作的线程和堆栈(比如-stack-list-variables --thread 1 --frame 0);
b)GDB/consle下有set language lan指令指定当前可执行文件对应的源文件的格式(默认auto),GDB/MI对应--language lan选项,但该选项没有auto
,故而在调用GDB/MI下调用C函数时,需要在其前面添加--language c选项。
5)GDB/MI的输入语法格式,在MI模式下支持console下面的大部分指令,所以可以直接输入console模式下的指令;另外它有一套自己的指令集合。下面说明
其合适,每一行的";"后面为该行的注释,nl表示回车键。
command → ; 下面一行表示可能的command指令集合类型
cli-command | mi-command ; cli-command表示GDB的console指令集中的指令,mi-command表示GDB的mi指令集中的指令
cli-command → ; console指令集的构成
[ token ] cli-command nl ; token是一个用于标识一条指令的数字序列,在对应的"Output Records"中会有对应该token的输出。
mi-command →
[ token ] "-" operation ( " " option )* [ " --" ] ( " " parameter )* nl ; 其中的" "表示空格
option →
"-" parameter [ " " parameter ]
parameter →
non-blank-sequence | c-string
operation →
any of the operations described in this chapter
non-blank-sequence →
anything, provided it doesn’t contain special characters such as "-", nl, """ and
Note1:所有的GBD/MI系统的指令都是以"-"开始的,指令的选项以"--"或者"-"为前缀,但是第一个选项必须以"--"为前缀。
Note2:GBD/MI系统可以处理几乎所有的GDB/console指令,但其输出跟console下会有所不同。不支持的指令主要包括"if","when","define"等涉及到多行
的指令,这些指令的共同点是会在一行的开始出现">"提示。但是可以通过将这些指令放到指令文件中,然后通过source指令导入实现。
6)GDB/MI的输出语法格式,输出由至少0个“out-of-band-record”和1个“result-record”构成。
output →
( out-of-band-record )* [ result-record ] "(gdb)" nl
result-record →
[ token ] "^" result-class ( "," result )* nl
out-of-band-record →
async-record | stream-record
async-record →
exec-async-output | status-async-output | notify-async-output
exec-async-output →
[ token ] "*" async-output nl
status-async-output →
[ token ] "+" async-output nl
notify-async-output →
[ token ] "=" async-output nl
async-output →
async-class ( "," result )*
result-class →
"done" | "running" | "connected" | "error" | "exit"
async-class →
"stopped" | others (where others will be added depending on the needs—this is still in development).
result →
variable "=" value
variable →
string
value → const | tuple | list
const → c-string
tuple → "{}" | "{" result ( "," result )* "}" ; 仅当为variable object时会出现tuple
list → "[]" | "[" value ( "," value )* "]" | "[" result ( "," result )* "]"
stream-record →
console-stream-output | target-stream-output | log-stream-output
console-stream-output →
"~" c-string nl
target-stream-output →
"@" c-string nl
log-stream-output →
"&" c-string nl
nl → CR | CR-LF
Note1:关于result-record,其基本格式如上所示。具体展开来如下所示,
a)"^done" [ "," results ],前面的指令操作成功,result是返回值;
b)"^running",与^done等价,主要用于"继续运行"程序时,一般下一行会是一个"Exec notifications"行---->*running,thread-id="all";
c)"^connected",调试远程设备时出现;
d)"^error" "," "msg=" c-string [ "," "code=" c-string ],前面的指令操作失败,msg=c-string中为相应的错误信息,code=c-string
中保存错误代码,当前只定义了一个错误代码"undefined-command";
e)"^exit",GDB退出。
Note2:log-stream-output是以"&"作为前缀的,它表示输出到日志文件的内容。
Note3:这里的console-stream-output就是3).d)的Console output notifications。
Note4:target-stream-output时目标程序产生的输出,它以"@"作为前缀。
7)GDB/MI中的流记录(stream records)。6)中的GDB的各种输出record可以看作是不同的输出流,GDB/MI通过流记录(stream records)来区分过滤
这些不同的输出。每一种流记录都有一个独特的前缀来标识该输出属于哪一个流。在前缀的后面是输出字符串(string-output),总结如下,
"~" string-output,表示console output stream
"@" string-output,表示target output stream
"&" string-output,表示log output stream
"*" string-output,表示exec-async-output stream
"=" string-output,表示notify-async-output stream
"+" string-output,表示status-async-output stream
"^" string-output,表示result output stream
------------------------>
------------------------>
a)可能的exec-async-output stream
*running,thread-id="thread",一般跟在^running后面表示程序正在运行,"thread"指明正在运行的线程,若"thread"为"all"表示所有线程都在运行;
*stopped,reason="reason",thread-id="id",stopped-threads="stopped",core="core",程序/远程目标已经停止运行, 并给出相应的信息。
"reason"为停止的原因,其可能的取值为:breakpoint-hit,watchpoint-trigger,read-watchpoint-trigger,access-watchpoint-trigger,function-finished,
location-reached,watchpoint-scope,end-stepping-range,exited-signalled,exited,exited-normally,solib-syscall-entry,signal-received,
solib-event,fork,vfork,syscall-return,exec。其具体含义参看P488(27.7.3 gdb/mi Async Records)。
b)可能的notify-async-output stream
=thread-group-added,id="id"
=thread-group-removed,id="id"
=thread-group-started,id="id",pid="pid"
=thread-group-exited,id="id"[,exit-code="code"]
=thread-created,id="id",group-id="gid"
=thread-exited,id="id",group-id="gid"
=thread-selected,id="id"
=library-loaded,...
=library-unloaded,...
=traceframe-changed,num=tfnum,tracepoint=tpnum
=traceframe-changed,end
=tsv-created,name=name,initial=initial
=tsv-deleted,name=name
=tsv-deleted
=tsv-modified,name=name,initial=initial[,current=current]
=breakpoint-created,bkpt={...}
=breakpoint-modified,bkpt={...}
=breakpoint-deleted,id=number
=record-started,thread-group="id"
=record-stopped,thread-group="id"
=cmd-param-changed,param=param,value=value
=memory-changed,thread-group=id,addr=addr,len=len[,type="code"]
其中,最常见的就是=breakpoint-开头的哪3个。
c)关于status-async-output stream,出现的很少
d)result output stream参见6)的Note1
e)console output stream应该是等效GDB/console下的输出
f)log output stream就是日志
g)target output stream也没见到过,应该是针对远程目标调试的
8)GDB/MI输出中的断点信息、堆栈结构和线程信息参见 和27.7.4 ~ 27.7.6(P490左右)
9)GDB/MI 的断点指令列表
| GDB/MI断点指令 | 对应console指令 |
|---------------------------------------|---------------------------|
| -break-after n num | ignore n num |
| -break-commands n ["cmd1"..."cmdN"] | commands n |不同之处在于,GDB/MI在一行中给出所有指令,以空格分隔
| -break-condition n expr | condition n exp |
| -break-delete [range] | delete [range] |
| -break-disable [range] | disable [range] |
| -break-enable [range] | enable [range] |
| -break-info [range] | info b [range] |
| -break-insert...[一堆选项] | break和tbreak |
| -dprintf-insert...[一堆选项] | dprintf... |
| -break-list | info b |
| -break-watch [ -a | -r ] | watch,rwatch,awatch |
| -catch-load [ -t ] [ -d ] regexp | catch load |
| -catch-load [ -t ] [ -d ] regexp | catch unload |
---------------------------------------------------------------------
10)程序的运行控制指令、查询类指令和堆栈操作指令
| GDB/MI指令 | 对应的console指令 |
|---------------------------------------|---------------------------|
| -thread-info [thread-id ] | info thread [thread-id] |
| -thread-list-ids | info thread的一部分 |
| -thread-select ID | thread ID |
| -exec-continue | continue |
| -exec-finish | finish |
| -exec-jump | jump |
| -exec-next | next |
| -exec-next-instruction | nexti |
| -exec-return | return |
| -exec-run | run |
| -exec-step | step |
| -exec-step-instruction | stepi |
| -exec-until | until |
| -stack-info-frame | info frame或frame |
| -stack-info-depth [ max-depth ] | 显示有多少层堆栈 |
| -stack-list-arguments 0|1|2 [lf hf] | 显示堆栈lf到hf的函数参数 |
| -stack-list-frames [lf hf] | bt |
| -stack-list-locals 0|1|2 | info locals |
| -stack-list-variables 0|1|2 | 在上面的基础上加上函数参数|
---------------------------------------------------------------------
11)GDB/MI中的变量对象(Variable Objects)
变量对象是用于查询和改变表达式的值的面向对象的MI接口,它是专门设计来用于给前端程序使用的。变量对象是一种复杂的数据类型(类似于C中的
struct类型或者matlab中的cell类型),它具有分层树形结构。如果前端程序要获取一个节点对象的子节点的值,则需要显式指定其名字。
默认情况下,一条指令只显示当前层的信息。如果子对象是一个指针,则其value为地址,若子对象为结构体,则value为{...}。
(下文中,将内置基本类型的变量对象称为叶变量对象--->leaf Variable Objects, LVO)
可以获取LVO的值,也可以给LVO赋值;但是非LVO节点,只能获取到表示其类型的字符串,而不能对其赋值。前端程序并不需要每次stop时都读取变量对象的
所有值,GDB/MI提供了一个update指令来列出两次update指令之间所有发生改变的变量对象。
R1
R11 R12 R13
R121 R122 R123 R131
R1311 R1312
变量对象的结构成为tuple,由一组属性名和属性值构成,常见的属性如下,
name,变量对象/变量对象的某个子对象的名字;
numchild,变量对象的子对象个数,或者变量对象的某个子对象的子对象的个数
value,变量对象/变量对象的某个子对象的标量值(只有简单的基本类型的值才有意义),对于结构体等复合类型没有意义;
type,变量对象/变量对象的某个子对象的类型;
has_more,有两个含义:创建变量对象时,对于非动态对象总为0;查询变量对象或其子对象时表示当前层后面还有没有其它变量对象。比如,
使用-var-list-children my_test 3 9,由于my_test由test定义而来,它有9个成员,所以后面没有别的了,故has_more=0;
使用-var-list-children my_test 3 8,由于最后还有一个联合体成员没有显示,故has_more=1;
dynamic,只出现dynamic类型的变量对象的属性中,不会出现在一般变量对象的属性中;
thread-id,如果一个变量对象绑定到一个具体的线程(执行指令时--thread id作为参数出现),则会出现在变量对象的属性中,否则不出现。
exp,变量对象/变量对象的某个子对象的表达式;
frozen,如果使用了-var-set-frozen指令冻结了一个对象,则为1,否则为0;
常用指令如下,{...}表示多选1,[...]表示可选项,...表示必选项
a)-var-create {name | "-"} {frame-addr | "*" | "@"} expression
S1 S2 S3 S4
创建变量对象,S2为给变量对象起的名字,如果为"-",则GDB给自动起名;
S3为指定计算expression时使用的变量所在的堆栈,*表示当前堆栈,@表示创建的是一个floating对象(进入的堆栈不同其值会变化);
S4为任意C语言表达式,或*addr(地址addr处的值),*addr1-addr2(地址addr1到addr2之间的所有内存值),$regname’(寄存器)。
b)-var-delete [ -c ] name
S1 S2 S3
删除变量对象,有S2时表示只删除变量对象name的子变量对象节点,否则全删除。
c)-var-set-format name {binary | decimal | hexadecimal | octal | natural}
S1 S2 S3
设置变量对象的输出格式,仅影响当层。
-var-show-format name
获取变量对象name显示格式。
d)-var-info-num-children name
获取变量对象name的子节点个数。
e)-var-list-children [print-values] name [from to]
S1 S2 S3 S4
列出变量对象name的子对象,只列出name的子对象,而对name的子对象的子对象并不给出。例如,若name为R1,则只会列出R11,R12和R13。
S2为显示格式,0 或 --no-values 表示只打印变量的名字,而不显示值,也就是没有value成员。默认;
1 或 --all-values 表示打印变量的值,指针变量的value会是地址,结构体等复合对象会是{...},数组为[num];
2 或 --simple-values 表示打印基本类型变量的值,符合类型变量和数组没有value成员。
S4表示从第from个子对象(zero-based)开始打印,一共打印to-from个子对象。比如,若{name,from,to}={R1,2,3},则只会打印R12。
f)-var-info-type name
返回变量对象name的类型,这里name或者是一个定义的变量对象,或者是一个已定义的变量对象的子对象。
g)-var-info-expression name
用于显示变量对象name的表达式,其值跟-var-list-children指令中显示的exp成员的值相同。
h)-var-info-path-expression name
跟g)作用相同,其区别在于显示表达式时会将前缀属于哪个类给上。比如(test为main.c中的结构体),
定义了 -var-create my_test * test,则
-var-info-expression msgs ----> ^done,lang="C",exp="msgT"
-var-info-path-expression msgs ----> ^done,path_expr="(test).msgs"
i)-var-show-attributes name
显示name的属性为 {{editable | noneditable} | TBD },两层,两个二选一,
基本数据类型为editable,复合数据类型为noneditable,内存地址区域为TBD。
j)-var-evaluate-expression [-f format-spec] name
显示变量对象的 value属性值,format-spec为输出格式,可以为{binary | decimal | hexadecimal | octal | natural}
k)-var-assign name expression
将变量对象name的值改为expression,其中,变量对象name的属性必须是editable,也就是说必须是基本类型。
这里,一般情况下只能对使用-var-create定义的变量对象的子对象中的基本数据类型赋值,而不能对子对象的子对象赋值;如果要对子对象的子对象赋值,
则需要先调用一次-var-list-children child1,然后就可以对child1的子对象中的基本数据类型赋值了,以此类推。
l)-var-update [print-values] {name | "*"}
S1 S2 S3
该指令执行后会做两件事:首先会更新 name变量对象 或 全部变量对象 中未frozen的对象及其子孙对象的值,然后跟更新前值不同,将变化了的通过
changelist列表返回给前端程序。手册上说name必须是一个根变量对象(root variable object),但通过测试发现,不是根对象也是完全可以的。
S2部分的含义参见e)。
S3中*表示所有的变量对象及其子孙变量对象。
m)-var-set-update-range name from to
设定变量对象name的更新范围,from to的含义与e)中相同。
这里的设定等效于:首先 -var-set-frozen name 1,然后再对name的子对象child_m(m属于from --- to-1)执行-var-set-frozen child_m 0。
这里针对的是其所有的子孙对象。
n)-var-set-frozen name {1|0}
设定值不被更新的变量对象,1表示frozen,0表示unfrozen,都是通过这一个指令实现。
这里的frozen是指不更新name的子孙对象的值,但比较仍然是做的。unfrozen并不做更新,直到后面碰到update才做更新。
o)-var-set-visualizer name visualizer
这个是python相关的指令,咱不说明。
12)GDB/MI中的数据操作(27.18 gdb/mi Data Manipulation)
a)-data-disassemble {[-s start-addr -e end-addr] | [ -f filename -l linenum [ -n lines ] ]} [--] mode
S1 S2 S3 S4
该指令等效于GDB/console中的 disassemble指令。
这里,S2和S3部分必须二选一
S2中表示指定起始汇编地址start-addr和结束汇编地址end-addr。这两个地址都可以是包含$pc的表达式,比如"$pc+20"。
S3表示将filename中linenum行附近的lines行源代码进行汇编
S4为汇编模式选项,可以为0-3,0表示只汇编显示,1表示混合代码显示,2表示汇编代码 + raw opcode,3表示在1的基础上 + raw opcode。
mode前面的--可以省略,不省略时,--与mode之间必须有空格。
比如,-data-disassemble -f main.c -l 20 3
通过输出发现,这种方式不适合人读,它是将每条汇编都作为一个tuple进行处理的,这种方式可以用于实现鼠标放在*.c的源码上显示其汇编,实现方式为:
-data-disassemble -f main.c -l 20 -n 1 3,显示main.c的第20行对应的汇编tuple。
b)-data-evaluate-expression expr
该指令等效于GDB/console中的 print或者output或者call指令。
表示计算表达式expr的值。
c)-data-list-register-names [ ( regno )+ ]
若不指定[ ( regno )+ ],列出当前处理器中所有的寄存器名以一个字符串数组的形势列出;
若指定[ ( regno )+ ],则只列出对应编号的寄存器名(zero-based),[ ( regno )+ ]为自然数,多个时以空格分隔。
例如, -data-list-register-names 0 2 3 表示显示第{0,2,3}个寄存器的名字。
d)-data-list-changed-registers
列出内容发生改变的寄存器编号。
e)-data-list-register-values [ --skip-unavailable ] fmt [ ( regno )*]
列出对应编号的寄存器的值,fmt表示格式,x Hexadecimal,o Octal,t Binary,d Decimal,r Raw,N Natural。
如果不给定[ ( regno )*],则列出所有寄存器的值。
f)-data-read-memory-bytes [ -o offset ] address count
S1 S2 S3 S4
该指令等效于GDB/console中的 x 指令。
从内存地址address偏移offset处读取count个byte。对于不可读的区域则跳过。
S3处必须是一个地址,对于变量需要使用取地址运算符。
例如,
-data-read-memory-bytes &test 10
^done,memory=[{begin="0x00406440",offset="0x00000000",end="0x0040644a",contents="6440400084fe28000000"}]
g)-data-write-memory-bytes address contents [count]
该指令可以使用GDB/console中的多个set {int}addr=num实现,或者使用第17小节中的restore实现。
表示将 contents 加载到address开始的内存中。count为可选项,如果不指定,则加载完contents就可以了;如果指定,则分两种情况,
若contents的长度大于count,则截断,若小于count,则重复加载contents。
13)GDB/MI中符号查询指令(27.20 gdb/mi Symbol Query Commands)
-symbol-list-lines filename
没看出什么意思来。
14)其它指令
GDB/MI指令 GDB/console指令 示例或解释
-file-exec-and-symbols file -file-exec-and-symbols main.exe
-file-exec-file exec-file 只加载可执行文件
-file-symbol-file symbol-file 只加载符号表
-target-download load 主要用于调试远程目标
-gdb-exit quit
-gdb-set set -gdb-set $foo=3
-gdb-show show -gdb-show annotate
-gdb-version show version
-list-thread-groups info thread
-add-inferior add-inferior 添加进程
clone-inferior
----------------------------------------------------------------------------------------------------------------------------------
27. x86的寄存器(IA-32架构)
1)8个通用寄存器(32位): EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP。一般情况下,ESP只用于表示堆栈指针。EBP和ESP之间为一个栈帧。
2)6个段寄存器(16位):CS, DS, ES, FS, GS, SS。CS为代码段寄存器;(DS, ES, FS, GS)为数据段寄存器,且DS为默认的数据段寄存器,
字符处理指令总是使用ES段寄存器作为目标操作数的段寄存器;SS为堆栈段寄存器。在IA-32架构下,段寄存器的值意义不大。
3)1个指令指针寄存器(32位):EIP。也就是PC。
4)1个标志寄存器(32位):EFLAGS,格式如下,
|------------- X -------------|S C X X |--------- S --------|
|0000000000|ID|VIP|VIF|AC|VM|RF|0|NT|IOPL|OF|DF|IF|TF|SF|ZF|0|AF|0|PF|1|CF|
21 13 12 0
其中,
a)IOPL标志占用2位,其它的标志都占用1位。0和1的位置表示保留值,不可修改。
b)32位的EFLAGS寄存器包含3种标志:状态标志(S)、系统标志(X)和一个控制标志(C)。
c)6个状态标志用于指示算术指令的结果:CF,进位标志(Carry Flag);PF,奇偶标志(Parity Flag);AF,辅助进位标志
(Auxiliary Carry Flag);ZF,零标志(Zero Flag);SF,有符号数标志(Sign Flag);OF,溢出标志(Overflow Flag)。
d)系统标志各位的含义:TF,陷阱标记(Trap Flag);IF中断使能标志(Interrupt enable Flag);IOPL,IO特权等级标志
(I/O Privilege Level Flag);NT,嵌套任务/中断标志(Nested Task Flag);RF,(Resume Flag)用于控制处理器对调试
异常的处理;VM,虚拟8086模式标志(Virtual-8086 Mode Flag);AC,内存对齐检测标志(Alignment Check Flag);VIF,
IF标志的虚拟映像(irtual interrupt flag);VIP,(Virtual Interrupt Pending Flag)该位置1以指示一个中断正在被
挂起,当没有中断挂起时该位清零。ID,(Identification flag)表示对CPUID指令的支持情况。
e)控制标志DF(Direction Flag),这个方向标志控制串指令(MOVS, CMPS, SCAS, LODS以及STOS)。设置DF标志使得串指令
自动递减(从高地址向低地址方向处理字符串),清除该标志则使得串指令自动递增。
f)一般情况下,程序执行过程中变化最多的是6个状态标志和1个系统标志IF。
5)FPU单元相关的寄存器,8个80位的ST0~ST7,控制寄存器fctrl,状态寄存器fstat,标志寄存器ftag,fiseg,foseg,fioff,fooff,操作码寄存器fop。
6)SSE指令集相关的向量寄存器:mm0~mm7,xmm0~xmm7。
----------------------------------------------------------------------------------------------------------------------------------
28. gdb交互方式的控制(22 Controlling gdb)
1)提示符(Prompt)
set prompt newprompt:更改console模式下的提示符为newprompt,默认为"(gdb) "
show prompt :显示当前console模式下的gdb提示符。
2)命令行历史记录(Command History)
set history filename fname :GDB的指令在退出时保存到的文件为fname。
set history save on :启用退出时的指令保存功能,默认为off。
set history size
#set history remove-duplicates
其它表示回看的条数,7.10版本刚加入的指令。
set history expansion
show history :显示已经做的设置。
3)GDB打印窗口的大小(Screen Size)
set height
show height
set width
show width
set pagination
show pagination
4)GDB中的数字基数设置(number's radix)
set input-radix base :设置输入数字的基数为base(012, 0x0a, 10等)
set output-radix base :设置输出数字的基数为base
show input-radix
show output-radix
show radix
5)其它
set confirm
show confirm
set trace-commands
show trace-commands