调试策略:使用二分法定位问题,打断点,而后按行执行观察数组
断点(b)和继续执行(c)指令函数
指令 b 能够在须要地方放置断点,使得程序在指令的位置中止运行,指令格式为 b 断点位置。其中,断点位置能够是行号,也能够是函数名(指定方式与 l 指令相似),也能够是地址。ui
b 10 //在源代码10行处放置断点spa
b main //在main函数开始处放置断点.net
b *0x80480000 //在存放在0x80480000处的指令处放置断点,直接使用地址时须要使用 *地址 的格式 指针
b 10 if a<10 //能够在断点中加入中断执行的条件,表示当a < 10 时才会中断程序执行调试
linenum 本地行号,即list命令可见的行号对象
filename:linenum 制定个文件的行号blog
function 函数,能够是自定义函数也但是库函数,如open进程
filename:function 制定文件中的函数
condtion 条件
在断点处检查完毕后,可使用 c 指定继续指令的执行。使用指令 disable/enable 断点号 能够启用/停用某断点。使用指令 d 可删除全部的断点,d 1 删除breakpoint 1.
显示(disp)和打印(p)指令
disp指令(display)能够在每次程序暂定时显示指定变量的值,指令格式为 disp 变量名。若输入的变量为数组名,则每次显示数组的全部元素,若为结构体,则输出结构体的全部成员的值。
disp temp //在每次程序暂停时输出指定的变量的值(确保程序在指定变量的做用域内执行,如某个在特定函数中的局部变量在程序进入该函数执行以前是没法被显示的)
undisplay //取消全部disp指定的自动显示变量
p指定(print)一样将变量的值打印出来,用法与diap相似,但结果只显示一次。
除变量外,p指令还能够输出给定寄存器、给定地址处的值。同时,能够经过一些参数对打印格式进行规定,如 /x 表示以16进制格式打印值,/t表示以二进制格式打印值。
p $eax //打印寄存器%eax存储的值,注意使用$标志寄存器名称
p /x ($ebp + 8) //以十六进制的格式打印%ebp + 8 的值
p /t 100 //以二进制格式输出100的值
p *0x08048000 //输出位于0x08048000处的数据(此处实际存放的是机器代码),注意地址需使用 * 标志,不然会被默认为常数
p *(int *)0xxxxxxxx //将指定地址处数据按照整数格式输出,这里通常须要指出指针类型方便gdb解释数据
其余显示类
info reg //输出全部寄存器的当前值
info frame //输出栈帧的使用状况
x 指令用于检查内存中某一区域的值,指令格式为 :x fmt address 。其中address为内存地址的表达式,fmt由 /重复次数+格式化字符+尺寸字符 组成。格式化字符有o(octal,八进制),x(hex,十六进制), d(decimal,十进制),u(unsigned decimal,无符号十进制),t(binary,二进制),f(float,浮点),a(address,地址),i(instruction,指令),c(char,字符),s(string,字符串).尺寸字符有 b(byte),h(halfword), w(word), g(giant, 8 bytes)
例:
x /4xb *0xxxxxx //将指定地址区域连续的四个字节以十六进制的格式输出,通常内存地址均使用 * 标识。
该指令的使用方法与C语言中的格式化输出函数类似
printf" %d , %d \n",X,Y //对于两个变量整形X,Y进行输出
使用指令whatis能够方便的得知所需对象的类型,如 whatis temp 会显示出temp的类型定义,在调试时有用。
s 与 n 指令都是表示执行下一条指令指令的意思。可是,当遇到函数调用时,s 指令会进入函数调用内部进行执行,即下一步为被调函数的第一指令,而 n 指令不进入函数调用内部,会将整个函数的执行过程看成一步执行。
回溯指令(backtrace)能够查看程序内存访问越界等错误信息,显示程序出错的位置,从而帮助定位程序错误。
info args
Print the arguments of the selected frame, each on a separate line.
info locals
打印出当前函数中全部局部变量及其值。
info catch
打印出当前的函数中的异常处理信息。
设置指令 set 能够将指定的变量的值修改成调试所须要的值。如对于一个int型的变量X,可使用 set X = 12 将变量的值进行设置。
可使用宏定义对一些经常使用指令进行定义。指令格式 :define 宏名,并根据提示输入宏定义,以end做为结尾标志。
gdb [exec file] [core file]
ulimit -c 能够设置core的文件,并能控制是否产生core文件,若是设置为0的话,将不产生core文件,若是设置的大小小于core文件,则对core文件截取.
打开core文件的限制,不限制core文件的大小,使程序能够产生core文件
ulimit -c unlimited
ulimit -c
/proc/sys/kernel/core_uses_pid能够控制core文件的文件名中是否添加pid做为扩展.文件内容为1,表示添加pid做为扩展名,生成的core文件格式为core.PID,为0则表示生成的core文件统一命名为core.
/proc/sys/kernel/core_pattern能够控制core文件保存位置和文件名格式,以下:
echo "/tmp/core-%e-%u-%s" > /proc/sys/kernel/core_pattern
%e表示添加命令名
%u表示添加当前uid
%s表示添加致使产生core的信号
强制生成core文件
第一种是发送信号给进程,以下:
kill -s SIGSEGV $$
而后编译连接运行,使用pprof生成分析结果 g++-o demo demo.cpp -lprofiler 运行demo,生成my.prof文件,而后用pprof命令对该文件解析,生成结果txt或pdf等。 pprof–text ./demo my.prof > output.txt pprof–pdf ./demo my.prof > output.pdf