开发中的辅助工具
来源:互联网 发布:电视直播软件清晰度 编辑:程序博客网 时间:2024/06/04 19:48
1 什么是开发环境
- 构建环境
- 代码编写,程序编译,版本控制(可选)
- 调试环境
- 用于定位问题的辅助工具集
- 测试环境
- 用于验证目标程序是否满足用户的显性需求和隐性需求
嵌入式开发中的时间分配:
- 代码编写及目标构建(20%)
- 测试,调试,bug修复(80%)
问题:如何提高开发效率?
- 工欲善其事,必先利其器
2 开发中的辅助工具
- GNU为GCC提供了配套的辅助工具集(Binutils)
- Binutils官网
3 addr2line
- 将指定地址转换为对应的文件名和行号(只能转换函数内的地址而不能是全局变量的地址)
- 常用于分析和定位内存访问错误的问题
addr2line示例:定位0地址访问
- 开启core dump
- ulimit -c unlimited
- 运行程序,并生成崩溃时的core文件
- 执行程序崩溃的测试用例
- 读取core文件,获取IP寄存器的值(0x08048000)
- dmesg core
- 使用addr2line定位代码行
- addr2line 0x08048000 -f -e test.out(-f:显示函数名,-e:指定文件)
4 strip
- 剔除程序文件中的调试信息,减少目标程序的大小
- 一般在程序发布前都需要将调试信息剔除
- 过多的调试信息可能影响程序的执行效率
- strip test.out
注意事项
- 几乎所有的调试工具都依赖目标文件中的调试信息
- 调试信息的运用能够快速定位问题
- 使用gcc编译程序时使用-g选项生成调试信息
- 发布程序时再考虑是否使用strip剔除调试信息
5 ar
- 打包目标文件
- ar crs libname.a x.o y.o(ar的c参数表示创建一个档案文件,r参数指示将文件增加到所创建的库中,s参数是为了生成库索引以提高库被链接时的效率)
- 解压目标文件
- ar x libname.a
6 nm
- 列出目标文件中的标识符(变量名、函数名)
- 输出结构由三部分组成:{地址、段、标识符}
- nm在编译时不需要加-g选项
段标识说明
int* g_pointer;int a;char c;void func(void){ *g_pointer = (int)"hello, lemon";}执行如下命令:gcc -g -c func.cnm fun.o运行结果如下:00000004 C a(对于段标识为C来说,4指的是所占内存的字节数,如下同理)00000001 C c00000000 T func00000004 C g_pointer
关于nm的疑问
代码如下:#include <stdio.h>int main(void){ printf("All is well...\n"); return 0;}执行如下命令:gcc -c test.c -o test.onm test.onm的结果如下:00000000 T main U putsprintf函数怎么变成了puts函数呢?这里发生了什么呢?执行的命令如下:gcc test.c -o test.outnm test.outnm的结果如下:0804a020 B __bss_start0804a020 b completed.68770804a018 D __data_start0804a018 W data_start08048360 t deregister_tm_clones080483d0 t __do_global_dtors_aux08049f0c t __do_global_dtors_aux_fini_array_entry0804a01c D __dso_handle08049f14 d _DYNAMIC0804a020 D _edata0804a024 B _end080484c4 T _fini080484d8 R _fp_hw080483f0 t frame_dummy08049f08 t __frame_dummy_init_array_entry080485d4 r __FRAME_END__0804a000 d _GLOBAL_OFFSET_TABLE_ w __gmon_start__080482b0 T _init08049f0c t __init_array_end08049f08 t __init_array_start080484dc R _IO_stdin_used w _ITM_deregisterTMCloneTable w _ITM_registerTMCloneTable08049f10 d __JCR_END__08049f10 d __JCR_LIST__ w _Jv_RegisterClasses080484c0 T __libc_csu_fini08048450 T __libc_csu_init U __libc_start_main@@GLIBC_2.00804841b T main U puts@@GLIBC_2.008048390 t register_tm_clones08048320 T _start0804a020 D __TMC_END__08048350 T __x86.get_pc_thunk.bx已经完成了链接工作,为什么还有这么多未定义的标识符呢?
7 objdump
反汇编目标文件,查看汇编到源码的映射
- objdump -d func.o(不需要包含调试信息)
- objdump -S func.o(需要包含调试信息)
查看目标文件中的详细信息
- objdump -h test.out
objdump -h输出说明
可执行程序是如何加载到内存中的?
三个重要的概念:虚存地址(VMA)、加载地址(LMA)、运行地址
桌面环境 :test.out(可执行文件),执行test.out会为其创建一个进程。首先会分配虚存,然后将相应的段加载到段所对应的虚存地址,这个虚存地址是在编译时确定的。这个虚存地址也就是加载目标地址,是终点的地址,简称加载地址。 最后执行应用程序。运行地址是指实地址。
嵌入式环境:源代码交叉编译得到test.bin,然后烧写到device的flash中。当flash为nandflash时,由于nand flash 只能存储代码不能执行代码,所以需要将代码从flash加载到ram中。 从flash的地址将代码拷贝到ram中,这个地址就叫加载地址,指的是起点。vma不等于lma ,这里的运行地址为实地址;当flash为norflash时, 代码可以直接在norflash中执行, 加载地址就是运行地址,虚存地址可能没有。
8 size
- 获取目标文件中的所有段大小(单位为byte)
- size test.out
9 strings
- 获取目标文件中的所有字符串常量
- strings test.out
阅读全文
0 0
- 开发中的辅助工具
- 开发辅助工具
- Web开发辅助工具介绍
- 开发常用辅助工具积累
- 各种开发辅助工具
- C#开发的辅助工具
- 开发常用辅助工具
- iOS开发辅助工具
- 常用.NET开发辅助工具
- 程序开发辅助工具
- AngularJS 开发辅助工具
- 开发辅助工具-ddms
- 日常使用开发辅助工具
- 常用开发辅助工具推荐
- iOS 开发常用辅助工具
- 程序员开发辅助工具总结
- 网站开发常用辅助工具
- 推荐使用开发辅助工具
- Java 关于 equals与操作符==的区别
- 这篇关于bitset类型的
- 算法系列——Group Anagrams
- ejs 中如length为0 会报错,要过滤一下,并不是和原有的div完全一样的;
- 编译Hadoop并给HBase应用Snappy本地库
- 开发中的辅助工具
- Bootstrap—轻松制作漂亮表格(table)
- Dijkstra&&Floyd
- 安装IntelliJ IDEA的一些配置
- 从JDK源码角度看Short
- C语言初步知识与基本数据类型(上)
- 650. 2 Keys Keyboard
- Spring Boot配置使用Mybatis
- 【牛腩】——sqlhelper层的优化旅程