目录

一、gcc使用

1.gcc简介

2.gcc编译链接过程

二、gdb调试

1.gdb简介

2.gdb调试命令

(1)准备工作【gcc -g test.c -o test】

(2)启动gdb 【gdb+程序名】

(3)查看程序源代码【list】

(4)设置断点 【break】

 (4)查看断点信息【info  break】

(5)调试程序运行【run】

(6)显示堆栈信息【backtrace】

(7)显示变量【print/whatis】

 (8)单步执行【step/next】

(9)继续执行【continue】

 (10)删除断点【delete/clear】

(11)退出gdb【quit】


一、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 ) :命令可以在遇到断点或异常而暂停执行时显示堆栈信息,显示栈帧之后,就可以看出程序在何处停止,以及程序的调用路径。

作用相同的还有whereinfo 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调试 。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐