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. 设置断点后程序在指定行之前停止
- gdb学习
- GDB学习
- gdb学习
- 学习GDB
- GDB学习
- gdb学习
- GDB学习
- gdb学习
- GDB学习
- GDB学习
- gdb学习
- 学习GDB
- [GDB-7] gdb 的学习
- 学习--GDB调试
- 开始学习gdb
- gdb 学习资料
- GDB/ARMulator 学习笔记
- gcc gdb 学习
- 输出随机数1到511*511序列
- BEGINNING SHAREPOINT® 2013 DEVELOPMENT 第6章节--在SharePoint2013中开发、集成和构建应用程序 总结
- 递归算法理解
- [Android Develop_004] Android Background Service
- 解决Eclipse空格自动补全问题
- gdb学习
- java volatile
- jdk 安装
- windows下运行的linux服务器批量管理工具(带UI界面)
- ubuntu下安装mysql出现FATAL ERROR: Could not find mysqld的处理
- merge用法(读书笔记)
- Mockups知识点
- [树莓派内核学习] u-boot移植
- 农历和阳历的相互转化