软件开发利器 - binutils工具集

版权声明:课程笔记内容整理于狄泰软件 https://blog.csdn.net/qq_39654127/article/details/87892268

目录

1、Binutils工具集

2、区分VMA与LMA


1、Binutils工具集

GNU为GCC编译器提供了配套的辅助工具集(Binutils))

           http://www.gnu.org/software/binutils/

addr2line

     - 将指定地址转换为对应的文件名行号

     - 常用于分析和定位内存访问错误的问题

//func.c
#include <stdio.h>

int* g_pointer;//0

void func()
{
    *g_pointer = (int)"D.T.Software";//对0地址处赋值

    return;
}
//test.c
#include <stdio.h>

int g_global = 0;
int g_test = 1;

extern int* g_pointer;
extern void func();

int main(int argc, char *argv[])
{
    printf("&g_global = %p\n", &g_global);
    printf("&g_test = %p\n", &g_test);
    printf("&g_pointer = %p\n", &g_pointer);
    printf("g_pointer = %p\n", g_pointer);
    printf("&func = %p\n", &func);
    printf("&main = %p\n", &main);
    
    func();
	
    return 0;
}

               如果有50万行代码如何快速定位错误?

addr2line 示例:定位0地址访问

    1. 开启core dump选项(程序奔溃的最后一刻记录内存信息,寄存器信息等)

           - ulimit -c unlimited

    2. 运行程序,并生成崩溃时的 core文件

           - 执行导致程序崩溃的测试用例

    3. 读取 core文件,获取IP寄存器的值0x08048000

           - dmesg core

    4. 使用addr2line定位代码行

           - addr2line 0x08048000 -f -e test.out

                几乎所有的调试辅助工具都依赖于目标文件中的调试信息,调试信息的运用能够快速定位问题

strip

     - 剔除程序文件中的调试信息,减少目标程序的大小

     - 一般在程序发布前都需要将调试信息剔除

     - 过多的调试信息可能影响程序的执行效率

ar

     - 打包目标文件  ar crs libname.a x.o y.o

     - 解压目标文件  ar x libname.a

nm

     - 列出目标文件中的标识符(变量名,函数名)

     - 输出结果由三部分组成:{地址标识符}

段标识说明

size

     - 获取目标文件中的所有段大小

        size test.out

strings

     - 获取目标文件中的所有字符串常量

        strings test.out

objdump

     - 反汇编目标文件,查看汇编到源码的映射

           objdump -d func.o

           objdump -S func.o

     - 查看目标文件中的详细段信息

           objdump -h test.out

objdump -h的输出说明

 

2、区分VMA与LMA

VMA(Virtual Memory Address):虚拟内存地址

LMA(Load Memory Address):加载内存地址

在桌面环境下执行可执行文件

  1. 分配虚存
  2. 将各个段从可执行文件加载到虚存中
  3. 执行程序

将test.out对应段拷贝到虚存的段的起始虚地址(段的详细信息就在test.out里,通过File off可以确定相应段的偏移位置)

桌面环境下LMA就是相应的段加载到虚存的目标位置处 即虚存地址

编译时段就已经确定虚存地址,确定的地址在哪就加载到哪

此时VMA == LMA

在嵌入式环境下

将程序烧写到目标设备的flash

★ Nand Flash 只能存储不能执行

Nand Flash对应的嵌入式设备:将烧写到flash中的程序加载到RAM中执行,上电后我们需要知道执行的代码具体在flash的哪个地址处,然后将具体地址的代码复制到RAM中执行,这个地址叫加载地址(从哪里将段拷贝到RAM)

此时VMA != LMA

★ Nor Flash 可以直接执行

Nor Flash对应的嵌入式设备: 上电后直接执行指令即可,此时加载地址就是Nor Flash里的地址,运行地址也是。此时很可能不存在虚存地址

VMA != LMA

猜你喜欢

转载自blog.csdn.net/qq_39654127/article/details/87892268