【Linux】Linux程序编译(gcc编译和gdb调试)
一、gcc使用1.gcc简介gcc命令使用GNU推出的基于C/C++的编译器,是开放源代码领域应用最广泛的编译器,具有功能强大,编译代码支持性能优化等特点。gcc是GNU编译器套件(GNU Compiler Collection),它包括了C、C++、Objective-C、Fortran、Java、Ada、Go语言和D语言的前端,也包括了这些语言的库(如libstdc++、libgcj等等)。G
目录
(1)准备工作【gcc -g test.c -o test】
一、gcc使用
1.gcc简介
gcc命令使用GNU推出的基于C/C++的编译器,是开放源代码领域应用最广泛的编译器,具有功能强大,编译代码支持性能优化等特点。
gcc是GNU编译器套件(GNU Compiler Collection),它包括了C、C++、Objective-C、Fortran、Java、Ada、Go语言和D语言的前端,也包括了这些语言的库(如libstdc++、libgcj等等)。GCC的初衷是为GNU操作系统专门编写的一款编译器。GNU系统是彻底的自由软件。此处,“自由”的含义是它尊重用户的自由。
2.gcc编译链接过程
①一个C语言源代码到可执行程序分那几个阶段:
(1) 预编译 :
gcc -E main.c -o main.i
(-o选项用来指定输出文件的文件名。)
(2) 编译:
gcc -S main.i -o main.s
(3) 汇编:
gcc -c main.s -o main.o
(4) 链接:
gcc main.o -o main
以上过程过于繁琐,如何简化以上工作呢?
一步走计划
gcc -o main main.c
两步走计划
gcc -c main.c -o main.o
gcc main.o -o main
②多文件编译
方法一
gcc test1.c test2.c -o test
(将test1.c和test2.c分别编译后链接成test可执行文件。)
方法二
gcc -c test1.c
gcc -c test2.c
gcc test1.o test2.o -o test
③调用外部函数库:加入链接的函数库
gcc test.c -lm -L/lib -L/usr/lib
解释:
- -l :加入某个函数库(Libary)
- m :是libm.so这个函数库(其中lib和扩展名.so不需要写)
所以-lm表示使用libm.so这个函数库。-L后面的路径表示我们要的函数库libm.so到/lib和/usr/lib里面搜索(Linux默认将函数库放置在/lib和/usr/lib中),所以没有写-L/lib -L/usr/lib没有关系;但是如果使用的函数库不在那俩个目录下,则-L/path就十分重要,否则就找不到函数库。
二、gdb调试
1.gdb简介
GNU symbolic debugger,简称「GDB 调试器」,是 Linux 平台下最常用的一款程序调试器。GDB 编译器通常以 gdb 命令的形式在终端(Shell)中使用,它有很多选项。
发展至今,GDB 调试器已经对 C、C++、Go、Objective-C、OpenCL、Ada 等多种编程语言提供了支持。实际场景中,GDB 更常用来调试 C 和 C++ 程序,虽然 Linux 平台下有很多能编写 C、C++ 代码的集成开发工具(IDE),但它们调试代码的能力往往都源自 GDB 调试器。
调试是开发流程中一个非常重要的环境,每个程序员都应具备调试代码的能力,尤其对于从事 Linux C/C++ 开发的读者,必须具备熟练使用 GDB 调试器的能力。
2.gdb调试命令
(1)准备工作【gcc -g test.c -o test】
编译一个测试程序,-g表示可以调试,命令如下:
(2)启动gdb 【gdb+程序名】
gdb test
(结果如下图:可以看到许多gdb的版本信息)
gdb -q test
(结果如下图:不打印版本信息,界面简洁)
(3)查看程序源代码【list】
list(简写 l): 查看源程序代码,默认显示10行,按回车键继续看余下的。
list相关命令
格式 | 说明 |
---|---|
list <linenum> | 显示程序第 linenum 行周围的源代码 |
list <function> | 显示函数名为 function 的函数的源代码 |
list | 显示当前行后面(10行)的源代码 |
list - | 显示当前行前面的源代码 |
list + | 往后显示源代码 |
list <first>,<last> | 显示从 first 行到 last 行之间的源代码 |
list ,<last> | 显示从当前行到 last 行之间的源代码 |
(4)设置断点 【break】
断点命令 break,简写为b,使用 【break + 断点】。
可以在函数名和行号等上设置断点。程序到达断点就会自动暂停运行。此时可以查看该时刻的变量值,显示栈帧、重新设置断点或重新运行等。
break相关命令
格式 | 说明 |
---|---|
break <函数名> | 对当前正在执行的文件中的指定函数设置断点 |
break <行号> | 对当前正在执行的文件中的特定行设置断点 |
break <文件名:行号> | 对指定文件的指定行设置断点,最常用的设置断点方式 |
break <文件名:函数名> | 对指定文件的指定函数设置断点 |
break <+/-偏移量> | 当前指令行+/-偏移量出设置断点 |
break <*地址> | 指定地址处设置断点 |
(4)查看断点信息【info break】
- Num: 断点编号
- Disp:断点执行一次之后是否有效【keep:表示有效 dis:表示无效】
- Enb: 当前断点是否有效 【y:表示有效 n:表示无效】
- Address:断点所在的内存地址
- What:断点所在的函数和行数信息
(5)调试程序运行【run】
run(简写 r ) :运行程序直到遇到断点等待下一个命令或文件末尾结束;
(6)显示堆栈信息【backtrace】
backtrace ( 简写 bt ) :命令可以在遇到断点或异常而暂停执行时显示堆栈信息,显示栈帧之后,就可以看出程序在何处停止,以及程序的调用路径。
作用相同的还有where和info stack。
(7)显示变量【print/whatis】
print (简写 p)命令可以显示变量 值,使用格式:print + 变量名
whatis命令显示变量的类型,使用格式:whatis + 变量名
(8)单步执行【step/next】
- next(简写 n):执行源代码中一行的命令。
- step (简写 s):执行时如果遇到函数调用,想执行到函数内部,使用step。
- 如果要逐条执行汇编指令,可以分别使用 nexti 和 stepi 命令。
(9)继续执行【continue】
continue(简写 c ):程序会在遇到断点后忽略当前断点到下一次断点暂停运行(或运行结束)。continue+num命令指定忽略断点的次数。
(10)删除断点【delete/clear】
delete(简写 d ):删除断点。使用:delete + 断点编号(表示删除编号指示的断点,编号查看命令: info backtrace)。
clear: 删除已定义的断点。 使用:clear + 行号(表示删除指定行的断点)
(11)退出gdb【quit】
quit(简写 q ):退出gdb调试 。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)