gcc./g++编译器以及gdb调试工具(c++)

gcc/g++是GUN编译器下的一个编译器组件。本文主要记录学习使用gcc/g++命令相关的参数,以及使用gdb工具对c++的调试。

gcc特点:

  1. 其是一个可以移植的编译器,支持多种硬件平台
  2. 不仅是个本地编译器,还可以跨平台交叉编译。如嵌入式程序可在x86上编译,然后在arm上运行。
  3. 有多种语言前端,用于解析不同语言
  4. 是自由软件,任何人都可以使用或更改这个软件

gcc和g++区别:

  1. 不管是gcc还是g++都可以编译C程序,编译程序的规则和参数都相同
  2. g++可以直接编译C++程序,gcc编译C++程序需要额外添加参数-lstdc++
  3. 不管是gcc还是g++都可以定义__cplusplus
    本文命令以g++为例示范

gcc工作流程

gcc编译器对程序的编译主要分为四个步骤。如下所示:

  1. 预处理:在这个阶段主要进行三件事:展开头文件、宏替换、去掉注释行(构建后得到的目标文件不包含注释内容,源文件中添加多少注释对最后的文件的大小没有影响。)
    此阶段需要gcc调用预处理器完成,最终得到是一个以.i后缀结尾的文件。
    例子:g++ -E t.cpp -o t.i
    注意:如果直接执行g++ -E t.cpp预处理的结果会显示到命令行屏幕上。
  2. 编译和优化:这个阶段需要GCC调用编译器对文件编译,最终将文件转换成汇编语言。文件通常以.s结尾。例子:g++ -S t.i -o t.s,或可直接由cpp文件得到,g++ -S t.cpp
  3. 汇编:该阶段调用汇编器对汇编文件进行汇编,得到一个.o结尾的二进制文件。g++ -c t.s -o t.o
  4. 链接:链接器将各种.o文件合并,并对文件需要调用的库进行链接,最终得到一个可执行的二进制文件.out文件(windows上是.exe文件),可以直接使用g++ t.cpp进行完成,若是有多个文件可以分开g++ t1.cpp t2.cpp如此,也可以使用通配符进行完成g++ *.cpp。该文件在汇编的基础上,增加了函数的具体信息和一些外部变量等等,最终可执行文件可被加载到内存中由操作系统执行。

gcc命令

常用选项:

  • -o 产生目标(.i、.s、.o、可执行文件等)
  • -E 只运行C预编译器
  • -S 告诉编译器产生汇编程序文件后停止编译,产生的汇编语言文件拓展名为.s
  • -c 通知gcc取消连接步骤,即编译源码,并在最后生成目标文件
  • -D 在程序编译时指定一个宏(类似在程序中定义的宏)
  • -Wall 使gcc对源文件的代码有问题的地方发出警告
  • -Idir 将dir目录加入搜索头文件的目录路径
  • -Ldir 将dir目录加入搜索库的目录路径
  • -llib 连接lib库
  • -g 在目标文件中嵌入调试信息,以便gdb之类的调试程序调试

g++命令

常用选项:

  • -B<directory> 将<director>添加到编译器的搜索路径
  • -v 显示编译器调用的程序
  • -### 类似于-v,但选项被引用,命令未被执行
  • -E 仅预处理;不要编译、汇编或链接
  • -S 仅编译;不要组装或连接
  • -c 编译和汇编,但不链接
  • -o<file> 将输出放入<file>。
  • -shared 创建共享库
  • -x 指定以下输入文件的语言。允许的语言包括:c++汇编程序无“none”表示恢复到默认行为,根据文件的扩展名猜测语言。

gdb调试

常用命令(以下都为程序简写)

  • gdb -p 进程id调试程序中正在运行的以id为进程编号的程序
  • gdb 程序名调试某程序
  • l [行号] 默认生成10行,查看正在调试的源码内容,显示的当前调试行的上下5行,可以不指定行号,指定后显示程序以行号为中心的10行代码
  • r 开始调试,直到程序结束或遇到断点暂停。在调试过程中,再次使用r命令会重新开始调试。
  • where 查看此时执行位置
  • b 行号 以l命令显示的内容为基础,在指定行打断点
  • info b显示全部断点信息,也可以在b后加编号显示指定断点
  • d 断点编号 删除指定断点,不加编号则删除全部
  • c 从当前调试位置直接执行到下一个断点处
  • disable 断点编号关闭断点 ,关闭断点并不是删除断点。只是在调试时不会在该处暂停,但是断点依旧存在。
  • enable 断点编号打开断点
  • p 变量 打印i对应的变量值,如p i,打印i变量的地址值,如p &i。也可以反过来使用变量的地址和变量的类型来打印出变量的值,这种同样适用于结构体等其它类型 p *(int *) 0x7fffffffdf54p *(int *) 0x7fffffffdf58
  • display 变量 常显示指定变量值,使用方式与p一致
  • undisplay 常显示变量编号 删除指定常显示变量
  • s逐语句调试,相当于vs中的F11
  • n逐过程调试,相当于vs中的F10
  • continue从当前位置开始运行,直到遇到下一个断点或者程序运行结束。
  • until 行号执行至指定行
  • finish 可以直接跑完当前函数,若函数只有一层则直接跑完函数。
    如果是函数递归调用,当还没开始递归时,finish会执行完整个函数,自动走完全部递归过程(前提无断点),如我们此时还在main函数中还没执行其中的func(n)函数,会直接执行完所有的递归func函数。如果已经开始进入func中,会执行完当前func返回上一层中。当已经递归调用后,在哪一层递归finish就会返回至它的前一层。
  • disassemble 查看指令附近区域的反汇编,只能在运行过程中使用。
  • shell 指令在gdb界面中执行linux指令
  • quit退出

首先要使用g++ -g t.cpp生成带有调试信息的可执行文件

/*
 * @Author: Xu 
 * @Date: 2023-03-13 10:22:03 
 * @Last Modified by:   Xu 
 * @Last Modified time: 2023-03-13 10:22:03 
 */

#include 
#include 
#include 
using namespace std;
int main()
{
    std::cout << __cplusplus << std::endl;
    cout << 1 << endl;
    return 0;
}   

接下来在生成的文件的命令行下输入gdb 文件名,本例为gdb t
注意:若是没有加-g参数,会出现No symbol “xxx” in current context,同时,gdp会自动记录最近的命令,如果没有输入其他命令,可以按enter键继续执行最近命令。

➜  gdb t       
GNU gdb (GDB) 8.2.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-w64-mingw32".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from t...done.

你可能感兴趣的:(linux,c++,linux,gnu)