Re: Reducing debug info for stack traces, while preserving for gdb

2022-12-14 Thread Witold Baryluk via D.gnu

For example to give you some context.

This is an example small app, the actual app is significantly 
larger (binary with debug symbols is about 20MB, without debug 
symbols only 2-3MB).


```
$ ~/bloaty/build/bloaty binary-O3-g-g3-gz  # (original binary)
FILE SIZEVM SIZE
 --  --
  19.8%   107Ki  39.3%   107Ki.text
  17.0%  93.0Ki   0.0%   0.strtab
  13.3%  72.4Ki   0.0%   0.debug_info   # 
72kB

  12.0%  65.3Ki  23.8%  65.3Ki.dynstr
   5.2%  28.5Ki  10.4%  28.5Ki.rodata
   5.1%  27.9Ki  10.2%  27.9Ki.eh_frame
   5.0%  27.5Ki   0.0%   0.debug_loclists   # 
27kB

   4.5%  24.8Ki   0.0%   0.symtab
   3.7%  20.4Ki   0.0%   0.debug_str# 
20kB
   3.4%  18.5Ki   0.0%   0.debug_line   # 
18.5kB

   3.2%  17.6Ki   6.4%  17.6Ki.dynsym
   1.3%  7.25Ki   0.0%   0[Unmapped]
   1.2%  6.61Ki   2.1%  5.64Ki[27 Others]
   1.1%  6.18Ki   2.3%  6.18Ki.eh_frame_hdr
   0.9%  5.08Ki   1.9%  5.08Ki.gnu.hash
   0.8%  4.31Ki   1.6%  4.31Ki.data.rel.ro
   0.8%  4.12Ki   1.5%  4.12Ki.rela.dyn
   0.5%  2.69Ki   0.0%   0[ELF Section Headers]
   0.4%  2.38Ki   0.0%   0.debug_rnglists   # 
small
   0.3%  1.74Ki   0.0%   0.debug_abbrev # 
small

   0.3%  1.52Ki   0.6%  1.52Ki.rela.plt
 100.0%   545Ki 100.0%   273KiTOTAL
```


```
$ ~/bloaty/build/bloaty binary-O3-g-g1-gz # binary with -g1, and 
compressed debug sections

FILE SIZEVM SIZE
 --  --
  24.4%   107Ki  39.3%   107Ki.text
  21.1%  93.0Ki   0.0%   0.strtab
  14.8%  65.3Ki  23.8%  65.3Ki.dynstr
   6.5%  28.5Ki  10.4%  28.5Ki.rodata
   6.3%  27.9Ki  10.2%  27.9Ki.eh_frame
   5.6%  24.8Ki   0.0%   0.symtab
   4.0%  17.6Ki   6.4%  17.6Ki.dynsym
   3.5%  15.5Ki   0.0%   0.debug_line  # 
smaller
   2.8%  12.2Ki   0.0%   0.debug_str   # 
smaller
   2.4%  10.4Ki   0.0%   0.debug_info  # way 
smaller

   1.6%  7.25Ki   0.0%   0[Unmapped]
   1.4%  6.18Ki   2.3%  6.18Ki.eh_frame_hdr
   1.2%  5.08Ki   1.9%  5.08Ki.gnu.hash
   1.0%  4.31Ki   1.6%  4.31Ki.data.rel.ro
   1.0%  4.20Ki   0.9%  2.43Ki[25 Others]
   0.9%  4.12Ki   1.5%  4.12Ki.rela.dyn
   0.6%  2.56Ki   0.0%   0[ELF Section Headers]
   0.3%  1.52Ki   0.6%  1.52Ki.rela.plt
   0.3%  1.47Ki   0.5%  1.47Ki.gnu.version
   0.2%  1.03Ki   0.4%  1.03Ki.plt
   0.2% 728   0.3% 728[ELF Program Headers]
 100.0%   441Ki 100.0%   273KiTOTAL
```

(`.debug_rnglists` and `.debug_abbrev` do not even register).





```
$ ~/bloaty/build/bloaty binary-O3-g-g3.exe  # without debug 
sections (broken lines in stack trace)

FILE SIZEVM SIZE
 --  --
  26.9%   107Ki  39.3%   107Ki.text
  23.2%  92.9Ki   0.0%   0.strtab
  16.3%  65.3Ki  23.8%  65.3Ki.dynstr
   7.1%  28.5Ki  10.4%  28.5Ki.rodata
   6.9%  27.9Ki  10.2%  27.9Ki.eh_frame
   6.2%  24.7Ki   0.0%   0.symtab
   4.4%  17.6Ki   6.4%  17.6Ki.dynsym
   1.8%  7.25Ki   0.0%   0[Unmapped]
   1.5%  6.18Ki   2.3%  6.18Ki.eh_frame_hdr
   1.3%  5.08Ki   1.9%  5.08Ki.gnu.hash
   1.1%  4.31Ki   1.6%  4.31Ki.data.rel.ro
   1.0%  4.12Ki   1.5%  4.12Ki.rela.dyn
   0.5%  2.12Ki   0.0%   0[ELF Section Headers]
   0.4%  1.52Ki   0.6%  1.52Ki.rela.plt
   0.4%  1.47Ki   0.5%  1.47Ki.gnu.version
   0.3%  1.18Ki   0.3% 881[18 Others]
   0.3%  1.03Ki   0.4%  1.03Ki.plt
   0.2% 728   0.3% 728[ELF Program Headers]
   0.1% 552   0.2% 552.data
   0.1% 544   0.2% 544.got.plt
   0.1% 512   0.2% 512.dynamic
 100.0%   401Ki 100.0%   273KiTOTAL
```

```
$ ~/bloaty/build/bloaty binary-O3-g-g3.debug   # only debug 
sections

FILE SIZEVM SIZE
 --  --
  31.0%   178Ki   0.0%   0.debug_info
   0.0%   0  39.3%   107Ki.text
  18.5%   106Ki   0.0%   0.debug_loclists
  16.8%  96.9Ki   0.0%   0.debug_str
  16.1%  93.0Ki   0.0%   0.strtab
   0.0%   0  23.8%  65.3Ki.dynstr
  10.5%  60.7Ki   0.0%   0.debug_line
   0.0%   0  10.4%  28.5Ki.rodata
   0.0%   0  10.2%  27.9Ki.eh_frame
   4.3%  24.8Ki   0.0%   0.symtab
   0.0%   0   6.4%  17.6Ki.dynsym
   0.0%   0   2.3%  6.18Ki.eh_frame_hdr
   1.0%  5.86Ki   0.0%   0.debug_rnglists
   0.0%   0   1.9%  5.08Ki.gnu.hash
   0.8%  4.54Ki   0.0%   0.debug_abbrev
   0.0%   0   1.6%  4.31Ki.data.rel.ro
   0.5%  2.79Ki   1.5%  4.17Ki[27 Others]
   0.0%   0   1.5%  4.12Ki.rela.dyn
   0.5%  2.69Ki   0.0%   0[ELF Section Headers]
   0.0%   0   0.6%  1.52Ki.rela.plt
   0.0%   0   0.5%  1.47Ki

Reducing debug info for stack traces, while preserving for gdb

2022-12-14 Thread Witold Baryluk via D.gnu

Hi,

I am trying to split debug symbols out of final binary, to reduce 
its size. But I would like to preserve at least line numbers in 
the stacktraces from `Exception`s.


Linux, amd64. gdc 12.2.0 on Debian testing.

Binary is compiled using `-O3 -g -g3` (and possibly -gz).

I then use `objcopy` to split debug info from final ELF binary 
file into .exe and .debug files.


I use `objcopy --only-keep-debug --compress-debug-sections=zlib 
binary binary.debug` to produce .debug file.


Then I use normally `objcopy --strip-debug binary binary.exe` 
(possibly with --compress-debug-sections=zlib) to produce binary.


This makes it possibly to use in gdb without issues (using `gdb 
-s binary.debug -e binary` for example, or by utilizing 
`--add-gnu-debuglink=` option in `objcopy`).


But this causes stacktraces to miss line numbers (and columns). 
(function names are still there, as these are derived from symbol 
tables instead).


I tried selectively removing DWARF debug sections, but it looks 
that at least these are required:


`.debug_info`
`.debug_aranges`
`.debug_abbrev`
`.debug_line`
`.debug_str`
`.debug_line_str`
`.debug_rnglists`

So, I can only remove these:

`objcopy -R .debug_loc -R .debug_macro -R .debug_ranges -R 
.debug_loclists`


(`.debug_loc` and `.debug_ranges` are not even generated by gcc, 
so it does not matter probably).


The issue is, this saves me very little space. `.debug_macro` and 
`.debug_loclists` are rather small.


The bulk of information is in `.debug_info`. But I believe it 
contains way more information than is really needed to just 
produce line numbers.




I did inspect final binaries , and it is using DWARF version 5.

I also tried `-gas-loc-support` , but no change.

Using `-g1` makes stack traces work nicely, by making 
`.debug_info` smaller, but then debugging in `gdb` is very 
limited. One option would be to compile application twice, once 
with `-g1` and once with `-g3`. But I really do not think this is 
supported, or reliable, even if I enable deterministic builds.


In one article ( 
https://support.backtrace.io/hc/en-us/articles/360040105792-DWARF#RemovingDebugInformation )  I read that for C/C++ in GCC, it is enough to preserve only `.debug_frame` and `.debug_line` to get function, source filenames and line numbers. But that is not true for gdc and its stacktrace handler.



I did read about this gdb extension, which is interesting, 
https://sourceware.org/gdb/onlinedocs/gdb/MiniDebugInfo.html , 
but I did not try, and it is probably only supported in gdb (i.e. 
addr2libe, Phobos, libunwind do not  support it).



Any ideas?