Linux下常用编译调试命令——gcc/g++与gdb工具的使用

GCC

  gcc是linux系统集成的编译器。在linux环境下编辑程序,首先需要克服的便是没有集成开发环境的一键式操作所带来的麻烦。这其中涉及命令行操作、编译选项的设定、文件依赖关系的书写(makefile)等问题。这里主要介绍的是关于gcc的常用命令行参数及其相应的作用。(若编译C++文件,则只需将下列命令的 gcc 换为 g++,源文件的后缀应为 .C/.cpp/.c++/.cc等)

 gcc/g++ 在执行编译工作的时候,总共需要4步:

  1. 预处理,生成 .i 的文件
  2. 将预处理后的文件转换成汇编语言, 生成文件 .s
  3. 有汇编变为目标代码(机器代码)生成 .o 的文件
  4. 连接目标代码, 生成可执行程序

GCC常用指令:

基本格式:gcc [options] file1 file2...  #若不加入参数,则按默认参数依次执行编译、汇编和链接操作,生成的可执行文件名为 a.out
常用参数:  -E						  #只进行预处理操作
          -S						  #只执行到编译操作完成,不进行汇编操作,生成的是汇编文件(.s 或 .asm),内容为汇编语言
          -c   						  #执行编译和汇编,但不进行链接,即只生成可重定位目标文件(.o),为二进制文件,不生成完整的可执行文件
          -o filename				  #将操作后的内容输出到filename指定的文件中
          -static            		  #对于支持动态链接的系统,使用静态链接而不是动态链接进行链接操作
       -g          		  #编译时生成debug有关的程序信息(供gdb使用)

GDB

  gdb是Linux下一款功能强大的调试工具,它既能在反汇编过程中充当一件称手的工具,也能在程序debug过程中为为程序员提供帮助,其唯一美中不足的是在Linux环境下没有图像界面(这也是gdb强大的原因之一)

 一般来说,gdb主要帮助你完成下面四个方面的功能:

  1. 启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。
  2. 可让被调试的程序在你所指定的调置的断点处停住。(断点可以是条件表达式)
  3. 当程序被停住时,可以检查此时你的程序中所发生的事。
  4. 可以改变你的程序,将一个bug产生的影响修正从而测试其他bug。

GDB常用指令:

开始/结束gdb:

 gdb filename

gdb以命令行环境运行,进入gdb后,程序会等待用户的指令并执行,直至用户选择退出。使用 qCtrl + d 退出。

(r)指令:

r #运行程序

List( l )指令:
可以使用指令 l 来列出源文件中的部分源代码。

l 10   #输出源程序10行及前后几行的源码,可以方便进行调试。若要继续查看,按回车键会继续向下显示。
l test.c:10 #输出test.c在前后10行的代码
l main #输出main函数的代码

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

b 10        #在源代码10行处放置断点
b main       #在main函数开始处放置断点
b *0x80480000   #在存放在0x80480000处的指令处放置断点,直接使用地址时需要使用 *地址 的格式 
b 10 if a<10    #可以在断点中加入中断执行的条件,表示当a < 10 时才会中断程序执行

在断点处检查完毕后,可以使用 c 指定继续指令的执行。使用指令 disable/enable 断点号 可以启用/停用某断点。使用指令 d 可删除所有的断点,d 1 删除breakpoint 1.

disable/enable    n        #停用/启用编号为n的断点
d                          #删除所有断点
d    n                     #删除标号为n的断点

观测点(watch)指令:
指令watch可以为某一表达式设置观察点,当程序执行过程中,当表达式的值发生改变时,则 gdb 会中断程序执行,并显示表达式的变化情况。

watch a      #当变量 a 的值发生变化时,中断程序执行
watch -l a    # watch指令指定了 -l 参数时,会将指令所接的表达式的计算结果作为地址,观察该地址处的值的变化情况
rwatch a      #当 a 的值被读取时,中断表达式的执行

显示(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命令:

info reg       #输出所有寄存器的当前值
info frame      #输出栈帧的使用情况
info  b n       #其中 n 为指定的断点号,显示指定断点的状态信息,不加参数 n 时,会显示所有的断点的信息

你可能感兴趣的:(Linux下常用编译调试命令——gcc/g++与gdb工具的使用)