一、什么是开发环境?
1、开发环境包括:构建环境,调试环境,测试环境。
构建环境 - 包括代码编写环境,程序编译环境,版本控制(可选)。
调试环境 - 用于定位问题的辅助工具集(如GCC提供的配套的辅助工具集Binutils)。
测试环境 - 用于验证目标程序是否满足用户的显性需求和隐形需求。
2、嵌入式开发中的时间分配
代码编写及目标构建(20%)
测试,调试。Bug修复(80%)
3、既然测试调试占开发的大部分时间,那么如何提高开发效率成了重中之重!
古人云:“工欲善其事,必先利其器”,这个“器”就是今天我们要说的GCC编译器提供的配套的辅助工具集(Binutils)
http://www.gnu.org/software/binutils/
由于这个工具集有很多工具,今天只挑选几个常用的介绍。
- addr2line
将指定地址转换为对应的文件名和行号,常用于分析和定位内存访问错误的问题。
addr2line主要用于当出现段错误的时候,找到出现段错误的文件名和行号。但是一般对于大型代码来说,运行的时候突然出现段错误是很难定位到出现段错误的地方的,但是addr2line可以。addr2line的addr指的是出现段错误的时候的IP地址,有了这个地址就可以定位到段错误的地点了。
比如,test.c文件里面有一个访问空指针的地方,编译正常,运行出错,那么如何找到段错误的地点呢?
步骤如下:
1) 编译生成带有调试信息的test.out
gcc -g test.c -o test.out
2) 开启core dump选项
ulimit -c unlimited
3) 运行test.out,并生成崩溃时的core文件
4) 读取core文件,获取IP寄存器的值(例如08048000)
dmesg core
5) 使用addr2line定位代码行
addr2line 0x08048000 -f -e test.out
最后一条指令运行之后,就会找到出现段错误的文件名和行号。
- strip
剔除程序文件中的调试信息,减少目标程序的大小
一般在程序发布前都需要将调试信息剔除
过多的调试信息可能影响程序的执行效率
使用方式: strip test.out
注意事项:
几乎所有的调试辅助工具都依赖于目标文件的调试信息
调试信息的运用能够快速定位问题
使用gcc编译程序时使用-g选项生成调试信息
发布程序时再考虑是否使用strip剔除调试信息
-ar
打包目标文件
ar crs libtest.a test.o
解压目标文件(得到test.o)
ar x libtest.a
-nm
列出目标文件中的标识符(变量名,函数名)
输出结果由三部分组成:(地址,段,标识符)
示例: 08048000 T func
08048000:标识符对应的地址
T:标识符位于的段(T是代码段)
func:标识符的名字
段标识说明:
A 地址值在链接过程中不会发生变化
B/b 标识符位于未初始化数据段(.bss)
C 未定义存储段的标识符,链接时决定段位置
D/d 标识符位于数据段(.data)
N 调试专用标识符
R/r 标识符位于只读存储区(.rdata)
T/t 标识符位于代码段(.text)
U 未定义的标识符
- objdump
反汇编目标文件,查看汇编到源码的映射
objdump -d fucn.o(查看汇编代码)
objdump -S func.o(查看汇编代码和汇编对应的源码)
查看目标文件中的详细段信息
objdump -h test.out
objdump -h 的输出说明
ldx 段下标
Name 段标识符(名字)
Size 段所占空间的大小
VMA 段地址位置的虚存地址
LMA 段在存储空间的加载地址
File off 段在目标文件中的相对位置
Algn 段的边界对齐字节数
- size
获取目标文件中的所有段的大小(由于资源受限的嵌入式设备)
size test.out
- strings
获取目标文件中的所有字符串常量
strings test.out
(版权声明:本文内容归狄泰软件所有,博主整理所得,未经博主允许不得转载。)