strip经常用来去除目标文件中的一些符号表、调试符号表信息,以减小静态库、动态库和程序的大小。其基本用法:
strip xxx
或者
strip xxx -o yyy
优点:strip后占空间小
缺点:strip后不方便调试,addr2line等不能使用
针对缺点的应对策略:strip前的库用来调试, strip后的库用来实际发布, 他们两者有对应关系。 一旦发布的strip后的库出了问题, 就可以找对应的未strip的库来定位。
可以直接调用strip去除大多数不必要的信息。
因为so库非常标准,所以strip之后仍然可以进行完美的动态连接;
而可执行文件已经进行了链接,所以也可以用strip进行完美的strip。
不能直接调用不带参数的strip,因为o文件大多数是relocate文件,如果去除的参数不恰当,在编译成so或可执行文件时就无法找到对应的符号。
拿我们之前的main可执行程序举例。
我们用如下命令得到strip后的二进制:
strip main -o main-strip
$ ls -al main main-strip
-rwxrwxr-x 1 wjbvb2 wjbvb2 8688 7月 24 22:00 main
-rwxrwxr-x 1 wjbvb2 wjbvb2 6320 7月 25 08:21 main-strip
可见strip前是8688字节,strip后变成了6320字节,变小了。
$ file main main-strip
main: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=805aad31cf417a9ae8e451701d53f3e85fc03522, not stripped
main-strip: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=805aad31cf417a9ae8e451701d53f3e85fc03522, stripped
$ readelf -s main main-strip
File: main
Symbol table '.dynsym' contains 4 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf@GLIBC_2.2.5 (2)
2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2)
3: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__Symbol table '.symtab' contains 69 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000400238 0 SECTION LOCAL DEFAULT 1
2: 0000000000400254 0 SECTION LOCAL DEFAULT 2
3: 0000000000400274 0 SECTION LOCAL DEFAULT 3
4: 0000000000400298 0 SECTION LOCAL DEFAULT 4
5: 00000000004002b8 0 SECTION LOCAL DEFAULT 5
6: 0000000000400318 0 SECTION LOCAL DEFAULT 6
7: 0000000000400358 0 SECTION LOCAL DEFAULT 7
8: 0000000000400360 0 SECTION LOCAL DEFAULT 8
9: 0000000000400380 0 SECTION LOCAL DEFAULT 9
10: 0000000000400398 0 SECTION LOCAL DEFAULT 10
11: 00000000004003c8 0 SECTION LOCAL DEFAULT 11
12: 00000000004003f0 0 SECTION LOCAL DEFAULT 12
13: 0000000000400420 0 SECTION LOCAL DEFAULT 13
14: 0000000000400430 0 SECTION LOCAL DEFAULT 14
15: 00000000004005e4 0 SECTION LOCAL DEFAULT 15
16: 00000000004005f0 0 SECTION LOCAL DEFAULT 16
17: 0000000000400604 0 SECTION LOCAL DEFAULT 17
18: 0000000000400640 0 SECTION LOCAL DEFAULT 18
19: 0000000000600e10 0 SECTION LOCAL DEFAULT 19
20: 0000000000600e18 0 SECTION LOCAL DEFAULT 20
21: 0000000000600e20 0 SECTION LOCAL DEFAULT 21
22: 0000000000600e28 0 SECTION LOCAL DEFAULT 22
23: 0000000000600ff8 0 SECTION LOCAL DEFAULT 23
24: 0000000000601000 0 SECTION LOCAL DEFAULT 24
25: 0000000000601028 0 SECTION LOCAL DEFAULT 25
26: 0000000000601038 0 SECTION LOCAL DEFAULT 26
27: 0000000000000000 0 SECTION LOCAL DEFAULT 27
28: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
29: 0000000000600e20 0 OBJECT LOCAL DEFAULT 21 __JCR_LIST__
30: 0000000000400460 0 FUNC LOCAL DEFAULT 14 deregister_tm_clones
31: 00000000004004a0 0 FUNC LOCAL DEFAULT 14 register_tm_clones
32: 00000000004004e0 0 FUNC LOCAL DEFAULT 14 __do_global_dtors_aux
33: 0000000000601038 1 OBJECT LOCAL DEFAULT 26 completed.7594
34: 0000000000600e18 0 OBJECT LOCAL DEFAULT 20 __do_global_dtors_aux_fin
35: 0000000000400500 0 FUNC LOCAL DEFAULT 14 frame_dummy
36: 0000000000600e10 0 OBJECT LOCAL DEFAULT 19 __frame_dummy_init_array_
37: 0000000000000000 0 FILE LOCAL DEFAULT ABS main.c
38: 0000000000000000 0 FILE LOCAL DEFAULT ABS mystaticlib.c
39: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
40: 0000000000400750 0 OBJECT LOCAL DEFAULT 18 __FRAME_END__
41: 0000000000600e20 0 OBJECT LOCAL DEFAULT 21 __JCR_END__
42: 0000000000000000 0 FILE LOCAL DEFAULT ABS
43: 0000000000600e18 0 NOTYPE LOCAL DEFAULT 19 __init_array_end
44: 0000000000600e28 0 OBJECT LOCAL DEFAULT 22 _DYNAMIC
45: 0000000000600e10 0 NOTYPE LOCAL DEFAULT 19 __init_array_start
46: 0000000000400604 0 NOTYPE LOCAL DEFAULT 17 __GNU_EH_FRAME_HDR
47: 0000000000601000 0 OBJECT LOCAL DEFAULT 24 _GLOBAL_OFFSET_TABLE_
48: 00000000004005e0 2 FUNC GLOBAL DEFAULT 14 __libc_csu_fini
49: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTab
50: 0000000000601028 0 NOTYPE WEAK DEFAULT 25 data_start
51: 0000000000601038 0 NOTYPE GLOBAL DEFAULT 25 _edata
52: 00000000004005e4 0 FUNC GLOBAL DEFAULT 15 _fini
53: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf@@GLIBC_2.2.5
54: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@@GLIBC_
55: 000000000040055b 20 FUNC GLOBAL DEFAULT 14 my_static_lib_func
56: 0000000000601028 0 NOTYPE GLOBAL DEFAULT 25 __data_start
57: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
58: 0000000000601030 0 OBJECT GLOBAL HIDDEN 25 __dso_handle
59: 00000000004005f0 4 OBJECT GLOBAL DEFAULT 16 _IO_stdin_used
60: 0000000000400570 101 FUNC GLOBAL DEFAULT 14 __libc_csu_init
61: 0000000000601040 0 NOTYPE GLOBAL DEFAULT 26 _end
62: 0000000000400430 42 FUNC GLOBAL DEFAULT 14 _start
63: 0000000000601038 0 NOTYPE GLOBAL DEFAULT 26 __bss_start
64: 0000000000400526 53 FUNC GLOBAL DEFAULT 14 main
65: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses
66: 0000000000601038 0 OBJECT GLOBAL HIDDEN 25 __TMC_END__
67: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMCloneTable
68: 00000000004003c8 0 FUNC GLOBAL DEFAULT 11 _initFile: main-strip
Symbol table '.dynsym' contains 4 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf@GLIBC_2.2.5 (2)
2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2)
3: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
由此看strip后符号少了好多好多。
$ nm -s main main-strip
main:
0000000000601038 B __bss_start
0000000000601038 b completed.7594
0000000000601028 D __data_start
0000000000601028 W data_start
0000000000400460 t deregister_tm_clones
00000000004004e0 t __do_global_dtors_aux
0000000000600e18 t __do_global_dtors_aux_fini_array_entry
0000000000601030 D __dso_handle
0000000000600e28 d _DYNAMIC
0000000000601038 D _edata
0000000000601040 B _end
00000000004005e4 T _fini
0000000000400500 t frame_dummy
0000000000600e10 t __frame_dummy_init_array_entry
0000000000400750 r __FRAME_END__
0000000000601000 d _GLOBAL_OFFSET_TABLE_
w __gmon_start__
0000000000400604 r __GNU_EH_FRAME_HDR
00000000004003c8 T _init
0000000000600e18 t __init_array_end
0000000000600e10 t __init_array_start
00000000004005f0 R _IO_stdin_used
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
0000000000600e20 d __JCR_END__
0000000000600e20 d __JCR_LIST__
w _Jv_RegisterClasses
00000000004005e0 T __libc_csu_fini
0000000000400570 T __libc_csu_init
U __libc_start_main@@GLIBC_2.2.5
0000000000400526 T main
000000000040055b T my_static_lib_func
U printf@@GLIBC_2.2.5
00000000004004a0 t register_tm_clones
0000000000400430 T _start
0000000000601038 D __TMC_END__main-strip:
nm: main-strip: no symbols
由此看strip后,nm都没有结果了。