详解GCC与GDB 常用的命令

时间:2021-07-23 02:19:07

LINUX下编程,少不了和GCC,GDB打交道,现在总结下常用命令,掌握这些足够用了。

GCC常用的选项:

-o

指定生成的输出文件,

-E

仅执行编译预处理

gcc的-E选项,可以让编译器在预处理后停止,并输出预处理结果。

-S

将C代码转换为汇编代码

gcc的-S选项,表示在程序编译期间,在生成汇编代码后停止

-wall

显示警告信息

-c

生成目标文件(.o),仅执行编译操作

 

gcc -o test test.c :一步到位编译指令,生成test可执行文件。

实质上,上述编译过程是分为四个阶段进行的,即预处理(也称预编译,Preprocessing)、编(Compilation)、汇编 (Assembly)和连接(Linking)。

单源文件--常用编译命令(以hello.c作为例子)

1.预处理(test.i)

 

gcc -E test.c -o test.i

将stdio.h 文件中的内容插入到test.c中生成test.i

2.编译为汇编代码(test.s)

 

gcc -S test.i -o test.s

将test.i文件生成test.s汇编文件

3.汇编

 

gcc -c test.s -o test.o

gas汇编器将汇编文件test.s汇编成目标文件test.o

4.链接

gcc连接器是gas提供的,负责将程序的目标文件与所需的所有附加的目标文件连接起来,最终生成可执行文件。附加的目标文件包括静态连接库和动态连接库。

gcc test.o -o test

test.o,将其与C标准输入输出库进行连接,最终生成程序test

最后我们把所有目标文件链接成可执行文件:

gcc –L/usr/dev/mysql/lib –lmysqlclient test.o –o test

Linux下的库文件分为两大类分别是动态链接库(通常以.so结尾)和静态链接库(通常以.a结尾),二者的区别仅在于程序执行时所需的代码是在运行时动态加载的,还是在编译时静态加载的。默认情况下,GCC在链接时优先使用动态链接库,只有当动态链接库不存在时才考虑使用静态链接库,如果需要的话可以在编译时加上-static选项,强制使用静态链接库


GDB

一般来说GDB主要调试的是C/C++的程序。要调试C/C++的程序,首先在编译时,我们必须要把调试信息加到可执行文件中。使用编译器(cc/gcc/g++)的 -g参数可以做到这一点。如:

    > gcc -g hello.c-o hello
    > g++ -g hello.cpp -o hello

如果没有-g,你将看不见程序的函数名、变量名,所代替的全是运行时的内存地址。当你用-g把调试信息加入之后,并成功编译目标代码以后,让我们来看看如何用gdb来调试他。

启动GDB的方法有以下几种:

    1gdb<program> 
       program也就是你的执行文件,一般在当然目录下。

    2gdb<program> core
      
gdb同时调试一个运行程序和core文件,core是程序非法执行后coredump后产生的文件。

    3gdb<program> <PID>
      
如果你的程序是一个服务程序,那么你可以指定这个服务程序运行时的进程IDgdb会自动attach上去,并调试他。program应该在PATH环境变量中搜索得到。

 

GDB启动时,可以加上一些GDB的启动开关,详细的开关可以用gdb-help查看。我在下面只例举一些比较常用的参数:

    -symbols<file> 
    -s <file> 
    从指定文件中读取符号表。

    -se file 
    从指定文件中读取符号表信息,并把他用在可执行文件中。

    -core <file>
    -c <file> 

    调试时core dumpcore文件。

    -directory<directory>
    -d <directory>
   
加入一个源文件的搜索路径。默认搜索路径是环境变量中PATH所定义的路径。

1 .启动gdb调试程序

    两种方式: A:gbd filename   B:启动gdb后,使用file filename

2.list(l)            查看程序(括号里为print缩写)

3 .break(b) 函数名    在某函数入口处添加断点

4 .break 行号         在指定行添加断点

5 .break 文件名:行号 在指定文件的指定行添加断点

6 .break 行号 if 条件 当条件为真时,在指定行号断点生效

   例如 b 5 if i=10

7 .infobreak         查看所有设置的断点

8 .delete 断点编号    删除断点

9.run(run)           开始运行程序

10.next(n)            单步运行程序(不进入子函数)

11.step(s)            单步运行程序(进入子函数)

12.continue(c)        继续运行程序

13.print(p) 变量名    查看指定变量值

14.finish             运行程序,直到当前程序结束

15.watch 变量名       对指定变量名进行监控

16.quit(q)            退出gdb