How do debug symbols affect performance of a Linux executable compiled by GCC?
所有其他因素都相等(例如,优化级别),ELF或SO中的调试符号将如何影响:
怎样减轻负面影响呢?
编辑
我已经看到了这个问题,但是我发现讨论没有帮助,因为代码优化因素使那里的问题感到困惑。 为什么在为性能分析(-pg)进行编译时,我的代码在多线程下的运行速度比单线程慢?
调试符号位于与代码/数据部分完全不同的部分。您可以使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | $ objdump -h a.out a.out: file format elf64-x86-64 Sections: Idx Name Size VMA LMA File off Algn 0 .interp 0000001c 0000000000400200 0000000000400200 00000200 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA 1 .note.ABI-tag 00000020 000000000040021c 000000000040021c 0000021c 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 2 .note.gnu.build-id 00000024 000000000040023c 000000000040023c 0000023c 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 3 .hash 00000018 0000000000400260 0000000000400260 00000260 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 4 .gnu.hash 0000001c 0000000000400278 0000000000400278 00000278 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 5 .dynsym 00000048 0000000000400298 0000000000400298 00000298 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 6 .dynstr 00000038 00000000004002e0 00000000004002e0 000002e0 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA 7 .gnu.version 00000006 0000000000400318 0000000000400318 00000318 2**1 CONTENTS, ALLOC, LOAD, READONLY, DATA 8 .gnu.version_r 00000020 0000000000400320 0000000000400320 00000320 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 9 .rela.dyn 00000018 0000000000400340 0000000000400340 00000340 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 10 .rela.plt 00000018 0000000000400358 0000000000400358 00000358 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 11 .init 00000018 0000000000400370 0000000000400370 00000370 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 12 .plt 00000020 0000000000400388 0000000000400388 00000388 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 13 .text 000001c8 00000000004003b0 00000000004003b0 000003b0 2**4 CONTENTS, ALLOC, LOAD, READONLY, CODE 14 .fini 0000000e 0000000000400578 0000000000400578 00000578 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 15 .rodata 00000004 0000000000400588 0000000000400588 00000588 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 16 .eh_frame_hdr 00000024 000000000040058c 000000000040058c 0000058c 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 17 .eh_frame 0000007c 00000000004005b0 00000000004005b0 000005b0 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 18 .ctors 00000010 0000000000600630 0000000000600630 00000630 2**3 CONTENTS, ALLOC, LOAD, DATA 19 .dtors 00000010 0000000000600640 0000000000600640 00000640 2**3 CONTENTS, ALLOC, LOAD, DATA 20 .jcr 00000008 0000000000600650 0000000000600650 00000650 2**3 CONTENTS, ALLOC, LOAD, DATA 21 .dynamic 000001a0 0000000000600658 0000000000600658 00000658 2**3 CONTENTS, ALLOC, LOAD, DATA 22 .got 00000008 00000000006007f8 00000000006007f8 000007f8 2**3 CONTENTS, ALLOC, LOAD, DATA 23 .got.plt 00000020 0000000000600800 0000000000600800 00000800 2**3 CONTENTS, ALLOC, LOAD, DATA 24 .data 00000010 0000000000600820 0000000000600820 00000820 2**3 CONTENTS, ALLOC, LOAD, DATA 25 .bss 00000010 0000000000600830 0000000000600830 00000830 2**3 ALLOC 26 .comment 00000039 0000000000000000 0000000000000000 00000830 2**0 CONTENTS, READONLY 27 .debug_aranges 00000030 0000000000000000 0000000000000000 00000869 2**0 CONTENTS, READONLY, DEBUGGING 28 .debug_pubnames 0000001b 0000000000000000 0000000000000000 00000899 2**0 CONTENTS, READONLY, DEBUGGING 29 .debug_info 00000055 0000000000000000 0000000000000000 000008b4 2**0 CONTENTS, READONLY, DEBUGGING 30 .debug_abbrev 00000034 0000000000000000 0000000000000000 00000909 2**0 CONTENTS, READONLY, DEBUGGING 31 .debug_line 0000003b 0000000000000000 0000000000000000 0000093d 2**0 CONTENTS, READONLY, DEBUGGING 32 .debug_str 00000026 0000000000000000 0000000000000000 00000978 2**0 CONTENTS, READONLY, DEBUGGING 33 .debug_loc 0000004c 0000000000000000 0000000000000000 0000099e 2**0 CONTENTS, READONLY, DEBUGGING |
您可以看到其他部分(27至33)。这些部分不会在运行时加载,因此不会有任何性能损失。使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | $ gdb ./a.out (gdb) break main (gdb) run (gdb) info files // blah blah .... Local exec file: `/home/kghost/a.out', file type elf64-x86-64. Entry point: 0x4003b0 0x0000000000400200 - 0x000000000040021c is .interp 0x000000000040021c - 0x000000000040023c is .note.ABI-tag 0x000000000040023c - 0x0000000000400260 is .note.gnu.build-id 0x0000000000400260 - 0x0000000000400278 is .hash 0x0000000000400278 - 0x0000000000400294 is .gnu.hash 0x0000000000400298 - 0x00000000004002e0 is .dynsym 0x00000000004002e0 - 0x0000000000400318 is .dynstr 0x0000000000400318 - 0x000000000040031e is .gnu.version 0x0000000000400320 - 0x0000000000400340 is .gnu.version_r 0x0000000000400340 - 0x0000000000400358 is .rela.dyn 0x0000000000400358 - 0x0000000000400370 is .rela.plt 0x0000000000400370 - 0x0000000000400388 is .init 0x0000000000400388 - 0x00000000004003a8 is .plt 0x00000000004003b0 - 0x0000000000400578 is .text 0x0000000000400578 - 0x0000000000400586 is .fini 0x0000000000400588 - 0x000000000040058c is .rodata 0x000000000040058c - 0x00000000004005b0 is .eh_frame_hdr 0x00000000004005b0 - 0x000000000040062c is .eh_frame 0x0000000000600630 - 0x0000000000600640 is .ctors 0x0000000000600640 - 0x0000000000600650 is .dtors 0x0000000000600650 - 0x0000000000600658 is .jcr 0x0000000000600658 - 0x00000000006007f8 is .dynamic 0x00000000006007f8 - 0x0000000000600800 is .got 0x0000000000600800 - 0x0000000000600820 is .got.plt 0x0000000000600820 - 0x0000000000600830 is .data 0x0000000000600830 - 0x0000000000600840 is .bss // blah blah .... |
因此,唯一的惩罚是您需要额外的磁盘空间来存储此信息。您还可以使用
1 | $ strip a.out |
使用
编辑:
取而代之的是查看加载器,实际上是加载器根据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | $ objdump -p /bin/cat /bin/cat: file format elf64-x86-64 Program Header: PHDR off 0x0000000000000040 vaddr 0x0000000000000040 paddr 0x0000000000000040 align 2**3 filesz 0x00000000000001f8 memsz 0x00000000000001f8 flags r-x INTERP off 0x0000000000000238 vaddr 0x0000000000000238 paddr 0x0000000000000238 align 2**0 filesz 0x000000000000001c memsz 0x000000000000001c flags r-- LOAD off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**21 filesz 0x00000000000078bc memsz 0x00000000000078bc flags r-x LOAD off 0x0000000000007c28 vaddr 0x0000000000207c28 paddr 0x0000000000207c28 align 2**21 filesz 0x0000000000000678 memsz 0x0000000000000818 flags rw- DYNAMIC off 0x0000000000007dd8 vaddr 0x0000000000207dd8 paddr 0x0000000000207dd8 align 2**3 filesz 0x00000000000001e0 memsz 0x00000000000001e0 flags rw- NOTE off 0x0000000000000254 vaddr 0x0000000000000254 paddr 0x0000000000000254 align 2**2 filesz 0x0000000000000044 memsz 0x0000000000000044 flags r-- EH_FRAME off 0x0000000000006980 vaddr 0x0000000000006980 paddr 0x0000000000006980 align 2**2 filesz 0x0000000000000274 memsz 0x0000000000000274 flags r-- STACK off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**4 filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw- RELRO off 0x0000000000007c28 vaddr 0x0000000000207c28 paddr 0x0000000000207c28 align 2**0 filesz 0x00000000000003d8 memsz 0x00000000000003d8 flags r-- |
程序头告诉哪个段将加载哪些rwx标志,具有相同标志的多个节将合并到一个段中。
顺便说一句:
加载程序在加载elf文件时并不关心各节,但在需要时它将查找几个与符号相关的节来解析符号。
您可能想看看为什么在为剖析(-pg)进行编译时,为什么我的代码在多线程下运行比单线程慢?快速了解调试符号如何影响优化。
要回答您的3个问题: