概述
通常公司发布的可执行程序和动态共享库(.SO)里面的符号表都被移除了,所以每次遇到core dump的时候,都需要将符号表导入到/usr/lib/debug目录下。一直没弄明白为啥是这个目录,能不能是其他目录,这篇文章探索一下相关的知识,做个记录。
我们要给我们生成的可执行文件和.SO瘦身,因为这样可以节省更多的磁盘空间,所以我们移除了debug信息,移除了符号表信息,同时我们还希望万一出事了,比如coredump了,我们能获取更多的信息,这时候我们又希望有符号表。
我们等不能做到呢。Linux下是怎么解决这个矛盾的呢?先看第一个问题,程序减肥。
1.程序减肥
1.1下面是简单的代码
main调用了foo,foo调用了bar,其中bar故意访问了非法地址,为了引起core dump。
tsh@tsh-virtual-machine:~/codeTest/segmentErr/stripTest$ cat stripTest.c
#include<stdio.h>
#include<stdlib.h>
int bar()
{
char *p = NULL;
fprintf(stderr,"I am bar,I will core dump\n");
fprintf(stderr,"%s",p);
return 0;
}
int foo()
{
int i ;
fprintf(stderr, "I am foo,I will call bar\n");
bar();
return 0;
}
int main()
{
fprintf(stderr,"I am main, I wll can foo\n");
foo();
return 0;
}
tsh@tsh-virtual-machine:~/codeTest/segmentErr/stripTest$
1.2 编译debug版本
先编译出一个debug版本来,然后我们看下可执行程序的大小
tsh@tsh-virtual-machine:~/codeTest/segmentErr/stripTest$ gcc -g -o stripTest stripTest.c
tsh@tsh-virtual-machine:~/codeTest/segmentErr/stripTest$ ll
total 24
drwxrwxr-x 2 tsh tsh 4096 Apr 30 10:23 ./
drwxrwxr-x 5 tsh tsh 4096 Apr 30 09:42 ../
-rwxrwxr-x 1 tsh tsh 11152 Apr 30 10:23 stripTest*
-rw-rw-r-- 1 tsh tsh 361 Apr 30 09:43 stripTest.c
tsh@tsh-virtual-machine:~/codeTest/segmentErr/stripTest$
1.3 查看section信息
tsh@tsh-virtual-machine:~/codeTest/segmentErr/stripTest$ readelf -S stripTest
There are 36 section headers, starting at offset 0x2290:
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .interp PROGBITS 0000000000400238 00000238
000000000000001c 0000000000000000 A 0 0 1
[ 2] .note.ABI-tag NOTE 0000000000400254 00000254
0000000000000020 0000000000000000 A 0 0 4
[ 3] .note.gnu.build-i NOTE 0000000000400274 00000274
0000000000000024 0000000000000000 A 0 0 4
[ 4] .gnu.hash GNU_HASH 0000000000400298 00000298
0000000000000024 0000000000000000 A 5 0 8
[ 5] .dynsym DYNSYM 00000000004002c0 000002c0
0000000000000090 0000000000000018 A 6 1 8
[ 6] .dynstr STRTAB 0000000000400350 00000350
000000000000004c 0000000000000000 A 0 0 1
[ 7] .gnu.version VERSYM 000000000040039c 0000039c
000000000000000c 0000000000000002 A 5 0 2
[ 8] .gnu.version_r VERNEED 00000000004003a8 000003a8
0000000000000020 0000000000000000 A 6 1 8
[ 9] .rela.dyn RELA 00000000004003c8 000003c8
0000000000000030 0000000000000018 A 5 0 8
[10] .rela.plt RELA 00000000004003f8 000003f8
0000000000000048 0000000000000018 AI 5 24 8
[11] .init PROGBITS 0000000000400440 00000440
000000000000001a 0000000000000000 AX 0 0 4
[12] .plt PROGBITS 0000000000400460 00000460
0000000000000040 0000000000000010 AX 0 0 16
[13] .plt.got PROGBITS 00000000004004a0 000004a0
0000000000000008 0000000000000000 AX 0 0 8
[14] .text PROGBITS 00000000004004b0 000004b0
0000000000000222 0000000000000000 AX 0 0 16
[15] .fini PROGBITS 00000000004006d4 000006d4
0000000000000009 0000000000000000 AX 0 0 4
[16] .rodata PROGBITS 00000000004006e0 000006e0
0000000000000055 0000000000000000 A 0 0 4
[17] .eh_frame_hdr PROGBITS 0000000000400738 00000738
0000000000000044 0000000000000000 A 0 0 4
[18] .eh_frame PROGBITS 0000000000400780 00000780
0000000000000134 0000000000000000 A 0 0 8
[19] .init_array INIT_ARRAY 0000000000600e10 00000e10
0000000000000008 0000000000000000 WA 0 0 8
[20] .fini_array FINI_ARRAY 0000000000600e18 00000e18
0000000000000008 0000000000000000 WA 0 0 8
[21] .jcr PROGBITS 0000000000600e20 00000e20
0000000000000008 0000000000000000 WA 0 0 8
[22] .dynamic DYNAMIC 0000000000600e28 00000e28
00000000000001d0 0000000000000010 WA 6 0 8
[23] .got PROGBITS 0000000000600ff8 00000ff8
0000000000000008 0000000000000008 WA 0 0 8
[24] .got.plt PROGBITS 0000000000601000 00001000
0000000000000030 0000000000000008 WA 0 0 8
[25] .data PROGBITS 0000000000601030 00001030
0000000000000010 0000000000000000 WA 0 0 8
[26] .bss NOBITS 0000000000601040 00001040
0000000000000010 0000000000000000 WA 0 0 32
[27] .comment PROGBITS 0000000000000000 00001040
0000000000000035 0000000000000001 MS 0 0 1
[28] .debug_aranges PROGBITS 0000000000000000 00001075
00000000000000