GCC/G++ 与 GDB

从hello world说起

  1. 首先我们有一段 hello world 程序
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include <iostream>

    using namespace std;

    int main()
    {

    retunr 0;
    }
  1. 我们通过以下步骤编译程序:
    • g++ hello.cpp
      这会生成一个a.out的文件,这个名字是由于历史原因导致的,所以不管源文件的名字是啥,生成的可执行文件的文件名都是一样的。
  2. 首先,认识一下文件的后缀
    • .c c语言的源文件
    • .cpp .C .cc .cxx c++ 语言的源文件
    • .i 经过预处理的c 文件
    • .ii 经过处理后的c++ 文件
    • .s 汇编代码源文件
    • .S 经过预处理的汇编代码文件
    • .h 头文件
    • .o 编译后的目标文件
    • .so 动态链接库文件 在Win下是 .dll
    • .a 静态链接库文件 在Win下是 .lib
  3. gcc 常用的命令
    • 一般格式: gcc [-option] srcfile [-option] desfile
    • g++ -E hello.cpp -o hello.ii 只进行预处理,得到预处理后的文件
    • g++ -S hello.cpp -o hello.s 生成到汇编代码后停止,得到汇编文件。
    • g++ -c hello.cpp -o hello.o 编译到最后的二进制代码,但不进行链接,得到目标文件。
    • g++ -g hello.cpp -o ghello 生成包含调试信息的可执行文件,可以通过strip ghello 删除文件中的debug信息。
    • g++ -O hello.cpp 对代码进行自动优化编译,O后面可以接数字,比如可以使用 -O3进行三级优化编译
    • g++ -W hello.cpp 编译中开启一些额外的警告信息,-Wall表示把所有的警告信息全部打开
    • g++ hello.cpp -I/path/to/include -L/path/to/lib -lnameoflib 分别表示添加包含文件的搜索路径,链接文件的搜索路径以及指定要使用的链接库的名字
  4. 链接库的生成,首先要介绍一些基本的规则
    • 动态库一律是以 lib 开头,制定链接库名字的时候可以省去lib三个字母。
    • 由于动态库节省空间,所以默认链接动态库,可就是说如果有两个同名的动态库和静态库,那么linux会优先选择动态库链接,如果要特别告诉编译器与重名的那个静态库链接,则主要加上-static-WI,-Bstatic选项,如果既要链接动态库又要链接静态库,则需使用-WI,-Bstatic -lnameofstaticlib -WI,-Bdynamic -lnameofdynamiclib
    • 为了让程序使用自己创建的动态库有三种方法
      • 将自己的库拷到 /usr/lib或/lib 等已经存在于环境变量中的动态库搜索路径中
      • 修改环境变量 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/new/lib/path
      • 修改 /etc/ld.so.conf ,把库的路径加到末尾,然后执行 ldconfig 刷新。
    • nm libname.so 查看库中有哪些函数,如果库中没有自己想要找的库,则可以使用 ldd libname.so 来看看它依赖的其他库,在其他库中说不定可以找到哦
    • 到达
  5. 生成库文件
    • ar cqs libname.a name.o
    • ar cr libnamme.a name.o
    • g++ -shared -W1,-soname,libname.so.1 -o libname.so.1.0 hello.o
    • g++ -shared -fPCI -o libname.so name.o
    • 其中soname 是库区分的标志,这就像库的身份证,通常的做法就是将库的soname与库的顶级版本号的保持一致,然后将低级版本到软连接到一个与soname同名的链接文件。

使用GDB调试程序

  1. 使用 gdb test 来启动调试。
  2. 一些常用的命令
    • r(run) pram1 parm2 运行
    • l(list) start,end 显示指定行数的代码
    • p(print) var(fun) 打印变量的值,或是打印函数调用的值
    • whatis 查看变量的类型
    • b(break) [行号,函数名] 在指定位置设置断点
    • tbreak 设置临时断点,触发后自动删除
    • info b 查看所有的断点
    • d(delete) 删除断点
    • set pram=val 设置变量的值
    • c(continue) 继续执行直到遇到新的断点
    • n(next) 不进入的单步调试
    • s(step) 进入的单步调试
    • finish 执行完当前函数
    • q(quit) 退出调试
    • h(help) command 查看指定命令的用法
T B
站点访问量: / , 本页阅读量:
T B