交叉编译命令:
arm-buildroot-linux-gnueabihf-strip
- 1
可以去除可执行文件中的符号信息和调试信息,进而减少生成的二进制文件的体积,使得生成的二进制文件更加紧凑,且不可读。对于生产环境中的可执行文件,strip
可以有效减小文件大小,提升加载速度。
那么问题来了,可执行文件中的符号信息和调试信息是怎么回事儿?
当我们提到 arm-buildroot-linux-gnueabihf-strip
去除的 符号信息 和 调试信息,我们指的是目标文件或可执行文件中,供编译器、调试器、链接器使用的信息。具体来说,这些信息包括符号表、调试信息、以及与程序调试和优化相关的其他内容。
以下是一些具体的符号信息和调试信息的例子:
1. 符号信息(Symbol Information)
符号信息是关于程序中函数、变量等的标识符和它们在内存中的位置。符号表包含了这些信息,用于编译、链接和调试。
-
符号表:符号表包含了程序中所有变量和函数的名称及其地址。它的作用是帮助编译器和链接器定位和解析函数、变量等符号。
示例:
- 函数符号:例如
main
、init
、my_function
。 - 变量符号:例如
g_variable
、my_array
。
- 函数符号:例如
-
符号信息的例子:
00000000 T _start 08048420 T main 08048460 B g_variable
- 1
- 2
- 3
其中,符号
main
是一个函数符号,它的地址为08048420
,而符号g_variable
是一个变量,它存储在.bss
段(通常是未初始化的全局变量区域)中,地址是08048460
。
2. 调试信息(Debug Information)
调试信息包含了源代码与生成的机器代码之间的映射。它通常在编译时通过添加 -g
选项生成,包含了源代码行号、函数名、变量名等信息,用于在调试时恢复源代码结构。
-
行号信息:记录了每个机器指令对应的源代码行号,调试器可以用这些信息来显示调试过程中的源代码。
-
变量和函数的类型信息:包括局部变量、全局变量、函数参数等的类型信息(如
int
、float
、struct
等)。 -
文件和函数名:调试信息包含了源文件名和函数名,用于帮助开发者在调试过程中识别和定位问题。
-
调试信息的例子:
.debug_info: 0x00000000 DW_TAG_compile_unit 0x00000004 DW_AT_name "main.c" 0x00000008 DW_TAG_subprogram 0x0000000c DW_AT_name "main" 0x00000010 DW_AT_type DW_FORM_ref4
- 1
- 2
- 3
- 4
- 5
- 6
这表示源文件
main.c
中的main
函数的调试信息,调试器可以通过这些信息知道main
函数在源代码中的位置,并映射到相应的机器代码指令。
3. 去除符号信息和调试信息的效果
当我们执行 strip
命令时,它会从目标文件或可执行文件中去除这些符号和调试信息,从而使得生成的二进制文件更加紧凑,且不可读。
示例:
假设我们有一个可执行文件 myprogram
,并使用 objdump
查看它的符号和调试信息:
arm-buildroot-linux-gnueabihf-objdump -t myprogram
- 1
输出可能包含符号信息(例如函数和变量名):
00008060 g F .text 00000034 main
00008094 g B .bss 00000004 g_variable
- 1
- 2
然后,执行 strip
命令:
arm-buildroot-linux-gnueabihf-strip myprogram
- 1
执行完毕后,再次使用 objdump
查看:
arm-buildroot-linux-gnueabihf-objdump -t myprogram
- 1
此时,可能会看到符号信息已经消失,输出变得更简洁,没有了函数名、变量名等信息:
00008060 g F .text 00000034
- 1
可以看到,原本的符号信息(如 main
和 g_variable
)已经被去除,strip
命令减少了可执行文件的体积,但去除了调试所需的符号和调试信息。
总结
- 符号信息:包括程序中的函数、变量的名称和地址。
- 调试信息:包括源代码行号、变量类型、函数调用信息等,用于调试时映射源代码和机器代码。
- 执行
strip
命令会去除这些信息,减少文件大小,但也使得调试变得更加困难,因为我们无法再查看源代码中的变量、函数名等符号。



评论记录:
回复评论: