gcc gdb 基础操作

本文操作均在 Linux 环境下完成

目录

GCC

1.创建源文件

2.预处理(-E)

3.编译(-S)

4.汇编:(-c)

5.链接(-O)

6.一步到胃

7. gcc -l 选项:手动添加链接库

GDB


GCC

要了解 gcc 的使用先要了解源代码 (.c) 文件生成可执行文件的过程,分为两个环境:

具体参考:https://blog.csdn.net/m0_46606290/article/details/120604689

程序的执行分为翻译环境和运行环境:

这里 gcc 完成的是翻译环境:

(1):预处理

(2):编译

(3):汇编

(4):链接

1.创建源文件

首先在当前目录下新建一个新目录并且切换到该目录下(mkcd),直接用 vim 在新目录中打开一个新的 hello.c 文件,写入后 wq 保存退出并展示(cat)hello.c 的内容:

关于 vim 的详细用法:http://c.biancheng.net/view/805.html

源文件已经生成,下面使用 gcc 操作将逐渐把它变成可执行的文件:

2.预处理(-E)

使用 gcc -E hello.c 命令将源文件的头文件展开:

 发现头文件展开后的文件直接显示在终端上,而发现目录下并没有 hello.i 文件,这是因为默认情况下 gcc -E 指令只会将预处理操作的结果输出到屏幕上,并不会自动保存到某个文件。因此该指令往往会和 -o 选项连用,将结果导入到指令的文件中。比如:

gcc -E hello.c -o hello.i

发现成功生成 .i 文件:

注意,这里的生成的 hello.i 文件是自定义名称,比如:

命名为 hello1.i 也会生成和 hello.i 内容一样的预处理文件。 

在此命令中加上 -C 指令会生成带注释的预处理文件(此处只让其显示而并不替换掉原 hello.i 文件):

(因为带注释的预处理文件太长所以展示下半部分) 

3.编译(-S)

gcc -S hello.i

令 gcc 仅将指定文件加工至编译阶段,并生成对应的汇编代码文件并且默认保存在当前文件下。例如:

还可以为 gcc -S 指令添加 -o 选项,令 gcc 将编译结果保存在我们指定的文件中:

 到这里可以看出来,实际上 -o 就是指定前方指令生成的文件应该保存在哪一个文件下

这里也可以直接对 hello.c 源文件进行 -S 编译操作,gcc 依旧会把程序运行到编译阶段,直接生成 .s 汇编文件,虽然不会生成中间的 .i 预处理文件,但实际上 gcc 也完成了预处理的操作

对于生成的汇编文件也可以加上注释,使用以下命令:

 gcc -S hello.c -fverbose-asm

 (生成了汇编注释)

4.汇编:(-c)

通过为 gcc 指令添加 -c 选项(注意是小写字母 c),即可让 gcc 将指定文件加工至汇编阶段,并生成相应的 .o 目标文件。例如:


同样,还可以在 gcc -c 指令后添加一个 -o 选项,用于将汇编操作的结果输入到指定文件中(在此不展示)


和 gcc -S 类似,gcc -c 选项并非只能用于加工 .s 文件。而是令 gcc 将指定文件加工至汇编阶段,但不执行链接操作。比如:

  • 如果指定文件为源程序文件(例如 hello.c),则 gcc -c 指令会对 hello.c 文件执行预处理、编译以及汇编这 3 步操作;
  • 如果指定文件为刚刚经过预处理后的文件(例如 hello.i),则 gcc -c 指令对 hello.i 文件执行编译和汇编这 2 步操作;
  • 如果指定文件为刚刚经过编译后的文件(例如 hello.s),则 gcc -c 指令只对 hello.s 文件执行汇编这 1 步操作。

 操作如下:

注意,如果指定文件已经经过汇编,或者 gcc 无法识别,则 gcc -c 指令不做任何操作。

5.链接(-O)

前面已经提到,gcc -o 用来指定输出文件,如果不使用 -o 选项,那么将采用默认的输出文件。例如默认情况下,生成的可执行文件的名字默认为 a.out

( a.out 和 hello.out 内容相同) 

链接格式为:    gcc [输入文件] -o [输入文件]

上列 gcc hello.c -o hello.out 相当于:将源文件( hello.c )作为输入文件,将可执行文件( hello.out )作为输出文件,完整地编译了整个程序

6.一步到胃:

也可以指定( -o ):

7. gcc -l 选项:手动添加链接库

vim 修改 hello.c 为如下内容:

 

发现错误提示为 pow 为定义,说明 <math.h> 库需要手动进行链接,此时就需要用上 -lm :

 

(链接成功)

参考于:GCC -E选项:对源程序做预处理操作



GDB

gdb : Linux 下使用最多的一款调试器(Debugger)

借助 gdb 调试器可以实现以下几个功能:

(1): 程序启动时,可以按照我们自定义的要求运行程序,例如设置参数和环境变量

(2):可使被调试程序在指定代码处暂停运行,并查看当前程序的运行状态(例如当前变量的值,函数的执行结果等),即支持断点调试

(3):程序执行过程中,可以改变某个变量的值,还可以改变代码的执行顺序,从而尝试修改程序中出现的逻辑错误。

gdb 的主要功能就是监控程序的执行流程。所以,只有当源程序文件编译为可执行文件并执行时,gdb 才会派上用场。

以 hello.c 源文件为例,其内容为:

正常情况下,使用 gcc 编译该源代码的指令如下:

可以看到,这里已经生成了 hello.c 对应的执行文件 hello.exe,但此文件不支持使用 gdb 进行调试。

注意,仅使用 gcc 命令编译生成的可执行文件,是无法借助 gdb 进行调试的

原因很简单,使用 gdb 调试某个可执行文件,该文件中必须包含必要的调试信息(比如各行代码所在的行号、包含程序中所有变量名称的列表(又称为符号表)等),而上面生成的 hello.exe 则没有。

这里只需要使用 gcc -g 指令编译源文件,即可生成满足 gdb 要求的可执行文件。

下面仍以 hello.c 源程序文件为例:

(不用删除上次操作产生的 hello.exe,直接执行 -g 会自动覆盖之前产生的同名的 .exe 可执行文件)

由此生成的 hello.exe,即可使用 gdb 进行调试。

开始调试

gdb hello.exe :

可以看到,该指令在启动 gdb 的同时,会打印出一堆免责条款。通过添加 --silent(或者 -q、--quiet)选项,可将部分信息屏蔽掉:

启动成功的标志就是最终输出的 (gdb),通过在 (gdb) 后面输入指令,即可调用 gdb 调试进行对应的调试工作。

下面列出了几个最常用的调试指令及各自的作用:

调试指令                                                        作 用

(gdb) break xxx

(gdb) b xxx           在源代码指定的某一行设置断点,其中 xxx 用于指定具体打断点的位置。

(gdb) run

(gdb)r                     执行被调试的程序,其会自动在第一个断点处暂停执行。

(gdb) continue

(gdb) c                   当程序在某一断点处停止运行后,使用该指令可以继续执行,直至遇到下一个断点或者程序结束。

(gdb) next

(gdb) n                     令程序一行代码一行代码的执行。

(gdb) print xxx

(gdb) p xxx               打印指定变量的值,其中 xxx 指的就是某一变量名。

(gdb) list

(gdb) l                       显示源程序代码的内容,包括各行代码所在的行号。

(gdb) quit

(gdb) q                       终止调试。

如上所示,每一个指令既可以使用全拼,也可以使用其首字母表示。

更多指令使用 (gdb) help 进行查看。

下列展示部分用法:

(gdb) l         ==>         显示带行号的源代码:

默认情况下,l 选项只显示 10 行源代码,若需查看后续代码,按 Enter 回车即可

(gdb) b 7         ==>         在第 7 行源代码处打断点:

(gdb) r         ==>         运行程序,遇到断点停止:

(gdb) p n         ==>         查看代码中变量 n 的值:

 当前 n 的值为 1,$1 表示该变量所在存储区的名称

(gdb) b 12         ==>         在程序第 12 行处打断点:

(gdb) c         ==>         继续执行程序:

(gdb) p n         ==>         查看当前 n 变量的值:

当前 n 的值为 101

(gdb) q         ==>         退出调试( y 确定):

参考于:http://c.biancheng.net/view/8153.html

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TGRD

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值