gcc/g++ 命令行参数& gdb调试

g++/gcc编译过程和动态链接库:https://my.oschina.net/u/347414/blog/1858115

gdb

调试策略:使用二分法定位问题,打断点,然后按行执行观察

  • 启动:gdb filename
  • 结束:q(quit)或 Ctril+d
  • 运行:r(run) 可以加参数
  • List(l):列出源文件中的部分代码; l 10 输出源程序10行及前后几行的源码,可以方便进行调试。对于多个文件的而言,可以通过 l source_file_name.c:col (l 源文件名:行号)来指定所需查看的源代码;l main       //输出main函数的源代码
  • 断点(b)和继续执行(c)指令

      指令 b 可以在需要地方放置断点,使得程序在指令的位置停止运行,指令格式为 b 断点位置。其中,断点位置可以是行号,也可以是函数名(指定方式与 l 指令类似),也可以是地址。

      b 10        //在源代码10行处放置断点

      b main       //在main函数开始处放置断点

  b *0x80480000    //在存放在0x80480000处的指令处放置断点,直接使用地址时需要使用 *地址 的格式 

  b 10 if a<10      //可以在断点中加入中断执行的条件,表示当a < 10 时才会中断程序执行

linenum                 本地行号,即list命令可见的行号

filename:linenum  制定个文件的行号

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      //输出栈帧的使用情况

  • 内存检查(examine)指令

  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  //将指定地址区域连续的四个字节以十六进制的格式输出,一般内存地址均使用 * 标识。

  •   格式化输出(printf)指令

  该指令的使用方法与C语言中的格式化输出函数相似

  printf" %d , %d \n",X,Y  //对于两个变量整形X,Y进行输出

  使用指令whatis可以方便的得知所需对象的类型,如 whatis temp 会显示出temp的类型定义,在调试时有用。

  

  •  执行(s与n)指令

  s 与 n 指令都是表示执行下一条指令指令的意思。但是,当遇到函数调用时,s 指令会进入函数调用内部进行执行,即下一步为被调函数的第一指令,而 n 指令不进入函数调用内部,会将整个函数的执行过程当作一步执行。

  •   回溯(bt)指令

  回溯指令(backtrace)可以查看程序内存访问越界等错误信息,显示程序出错的位置,从而帮助定位程序错误。

info args
Print the arguments of the selected frame, each on a separate line.
info locals
打印出当前函数中所有局部变量及其值。
info catch
打印出当前的函数中的异常处理信息。 

  •   设置(set)指令

  设置指令 set 可以将指定的变量的值修改为调试所需要的值。如对于一个int型的变量X,可以使用 set X = 12 将变量的值进行设置。

  •   使用宏定义

  可以使用宏定义对一些常用指令进行定义。指令格式 :define 宏名,并根据提示输入宏定义,以end作为结尾标志。

用gdb查看core文件

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

转载于:https://my.oschina.net/u/347414/blog/478512

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值