gdb学习

来源:互联网 发布:管家婆软件哪里买 编辑:程序博客网 时间:2024/06/05 05:13

GCC

 

程序编译过程

 

从程序员角度,编译源代码可以分为三个阶段。预处理源代码(宏展开),生成机器指令(*.o),链接(*.a *.so),如下图

 

GCC是GNU Compiler Collection的缩写,gcc/g++都可以编译C或者C++代码。无论源文件的后缀是.c还是.cpp,g++都认为是C++源文件。gcc严格按照后缀来区分源文件。.c是c代码,.cpp是c++代码。gcc不能自动链接C++库。(需要选项 -lstdc++ )。一般情况下 ,我们用gcc编译c代码,g++编译c++代码。

•          有一个main.c,用gcc通过以下几个步骤编译成最终可执行文件。

Ø            gcc -c main.c  生成main.o的对象文件。

Ø            gcc  main.o –o main  生成可执行文件

Ø            ./main   运行可执行文件

Ø            gcc main.c –o main 一步生成可执行文件。

 

gcc常用编译选项

•          -c:编译或汇编源文件,但是不作连接.编译器输出对应于源文件的目标文件。缺省情况下, GCC通过用’.o‘替换源文件名后缀’.c’,产生目标文件名。可以使用-o选项选择其他名字。连接器可把一个或多个’.o’链接撑最终的可执行文件。

范例:

      gcc –c main.c  -o main.o

 

•          -S:大S。编译后即停止,不进行链接。输出汇编语言文件。

范例:把c代码编译成汇编代码。

        gcc –S main.c –o main.s

 

•          -D: 宏定义选项,等同于代码中的#define MACRO 但-D定义的宏作用于所有的源文件。

范例: 演示gcc宏选项的作用。

     gcc  -DTEST main.c

     gcc  main.c

 

•          -I 头文件的搜索路径。如果用户的头文件不在gcc的搜索路径中,可以用此选项指定额外搜索路径。

•          -Wall  打开所有警告。

•          -Werror  把警告当做错误,必须与-Wall配合使用。

•          -w   关闭所有警告。

•          -g    加入调试信息。(可执行文件体积增大,运行速度变慢)

•          -O 或者 –O1 优化选项

•          -O2   一般使用2级优化。

•          -O3  乱序执行,循环展开的优化。

gdb调试时不能用优化选项,否则变量值和源代码无法对应。

 

外部库的使用

 

库使用方式

 

优点

缺点

静态链接库(*.a)

在程序链接时,就把第三方的库文件链接进可执行文件。

不依赖于具体执行环境。

编译速度慢,可执行文件占用空间大,运行时耗内存。

动态链接库(*.so)

程序链接时,只把依赖的动态链接库的库名放入可执行文件中

编译速度快,编译后的执行文件占用空间小,省内存。

依赖于具体执行环境是否有程序使用的第三方库。

动态装载外部库(*.so)

链接时什么都不做。程序运行时,调用dlopen,dlsym来动态的调用第三方库中的代码。

需要时在装载,省内存。

依赖于具体执行环境是否有程序使用的第三方库。

 

静态库编译和使用

•          把 ‘.c’编译成 ‘.o’    

        gcc –c increase.c –o increase.o

•          把 ‘.o’归档成 静态库‘.a’ 

       ar –r  increase.a  increase.o

•          静态库和其它源文件链接成可执行文件

       gcc main.c increase.a –o main

•          执行main即可得到结果

•          -static 使用静态库链接。编译后的文件体积较大。

     gcc main.c increase.a –o main –static

(用ldd观察静态链接和动态链接的区别)

 

动态库编译

 

•          动态库编译-shared 生成共享文件

•          -fPIC   生成位置独立的代码,此类代码可以在不同进程间共享。

•          范例生成动态链接库

    gcc -shared -fPIC -o libinc.so increase.c

•          动态链接库的名字必须以lib开头 .so结束,这是linux系统上的强制约束,否则无法使用该共享库。

 

动态库的使用

•          -llibrary  名字为library的动态链接库。事实上此动态链接库在文件系统中的名字为liblibrary.so。连接器会自动加上lib*.so。

•          -Ldir  共享库搜索目录。gcc除了会在自定义的目录中搜索共享库外,用户也自定义目录让gcc搜索。

    gcc main.c -o main -linc -L./

•          LD_LIBRARY_PATH 动态库加载时的搜索目录。如果没有把inc动态库所在的路径加入到此环境变量。那么linux系统运行main程序时会提示:/usr/bin/ld: cannot find -linc

 

 

 

 

 

 

 

 

 

 

GDB

 

GDB是一款Linux下的程序调试工具,功能非常强大。

 

1.       写一个测试程序,是没有错误的,但是也可以方便学习调试流程

 

编译,打开gdb,出现gdb相关信息

相关命令:l :list 打印出代码和行号

 

 

命令 : b 设置断点 后面是行号

        info b  查看断点信息

        r  运行

        p 打印变量 如p n; p i 这里的i是未初始化的 所以值是随机的

        一下2个都是单步运行,区别在于由函数调用的时候next不会进入函数,step则会进入函数

              n (next)

        s (step)

        c (continue) 恢复程序的正常运行,显示剩余程序的执行结果

 

GDB下面有很多命令,可以使用help查看

 

Gdb中设置断点的方式有很多种,前面只介绍了行号设置,还有其他方法

 

1.       函数断点

只需把函数名列在命令b 之后

2.       条件断点

        b 15 if i==10

            delete 1 删除1号断点

          注意设置为15其实函数跑完14行的时候停止

 

db中修改运行参数相关命令

       set 变量 = “设定值” 那么变量的初值会变化

 

最后几点使用切记

1.  编译时加入-g

2.  查看变量只有在运行和暂停状态

3.  设置断点后程序在指定行之前停止

0 0
原创粉丝点击