使用nm工具时同类型变量大小显示异常,如何获取真实大小?
nm显示静态char变量大小异常?教你查看真实大小
问题背景
测试代码test.c:
static char test1 = 0; static char test2 = 0; char test_f(void) { test1 = test2; return test2; } int main(void) { return test_f(); }
执行nm命令查看符号:
gcc test.c nm -C -S --size-sort a.exe | findstr /rc:"test"
输出结果中,test2的大小显示为0xf(15字节),远超char类型的实际大小1字节:
0000000140007040 0000000000000001 b test1 0000000140007041 000000000000000f b test2 0000000140001540 000000000000001a T test_f
原因解析
nm的-S参数计算的是当前符号地址到下一个符号地址的区间长度,而非变量的实际类型大小。
这里test2所在的数据段为了满足内存对齐要求(比如对齐到16字节边界),编译器在test2后面填充了14个空字节,nm把从test2地址到下一个符号的总长度(1+14=15)当成了它的“大小”,但这些填充字节不属于test2本身。
查看真实大小的方法
有几种方式可以获取变量的实际大小:
用objdump替代nm
objdump会显示符号的类型信息,你可以直接根据类型判断大小,或者查看更精确的符号数据:objdump -t a.exe | findstr /rc:"test"若需要上下文辅助,可添加范围参数:
objdump -x a.exe | findstr -A 2 -B 2 "test"根据变量类型直接确认
C标准规定char类型的大小固定为1字节,只要你明确变量的类型,就能确定它的真实大小,无需理会nm显示的包含填充的区间长度。用readelf(适用于ELF格式程序)
如果是生成ELF格式的gcc环境,readelf的符号表会明确标记符号的实际大小:readelf -s a.out | grep test
内容的提问来源于stack exchange,提问作者Dmitry Grigoryev
相关产品推荐
相关产品推荐

