Skip to content
This repository has been archived by the owner on Jun 28, 2022. It is now read-only.

Ship debug information in a separate file from the shared library #29

Merged
merged 1 commit into from
Feb 23, 2022

Conversation

ivoanjo
Copy link
Member

@ivoanjo ivoanjo commented Feb 23, 2022

What does this PR do?

Modifies ffi-build.sh to place the debug information for the shared library version of libddprof into a separate file.

Motivation

By shipping the debug information in a separate file, downstream packages (e.g. the Ruby packages) can easily remove the debug information while packaging libddprof, but it's still very easy to restore it.

Additional Notes

This approach is documented in https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html and in the objdump man pages. Thanks @nsavoire for the tips.

The strip'd file retains the build-id information.

I've tested with gdb and it seems to work:

$ gdb libddprof_ffi.so
GNU gdb (Ubuntu 11.1-0ubuntu2) 11.1

Reading symbols from libddprof_ffi.so...
Reading symbols from /working/build-linux-amd64/lib/libddprof_ffi.so.debug...

(gdb) info functions
All defined functions:

File /cargo/registry/src/git.luolix.top-1ecc6299db9ec823/addr2line-0.13.0/src/lib.rs:
966:	static fn addr2line::Function::parse_children<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>();
549:	static fn addr2line::ResUnit::parse_functions<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>();
480:	static fn addr2line::ResUnit::parse_lines<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>();
660:	static fn addr2line::name_attr<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>();
1162:	static fn addr2line::{{impl}}::for_each_range::{{closure}}<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>,closure-0>();

File /cargo/registry/src/git.luolix.top-1ecc6299db9ec823/compiler_builtins-0.1.32/src/macros.rs:
262:	fn compiler_builtins::int::udiv::__udivmodti4();
269:	fn compiler_builtins::int::udiv::__umodti3::__umodti3();
...etc...

and if the .debug file is deleted:

(gdb) info functions
All defined functions:

Non-debugging symbols:
0x0000000000075d00  _init
0x0000000000075d30  __stack_chk_fail@plt
0x0000000000075d40  __tls_get_addr@plt
0x0000000000075d50  __fxstat64@plt
0x0000000000075d60  __gmon_start__@plt
0x0000000000075d70  _Unwind_Resume@plt
0x0000000000075d80  __cxa_finalize@plt
0x0000000000075dc0  deregister_tm_clones
0x0000000000075df0  register_tm_clones
0x0000000000075e30  __do_global_dtors_aux
0x0000000000075e70  frame_dummy
0x0000000000075ea5  std::error::<impl core::convert::From<E> for alloc::boxed::Box<dyn std::error::Error>>::from
0x0000000000075edd  std::error::Error::description
0x0000000000075eea  std::error::Error::cause
...etc...

This PR is an alternative to #28, which instead shipped two copies of the shared library binaries (one stripd, and an untouched one).

How to test the change?

  1. Check that the stripped libddprof_ffi.so works correctly
  2. Confirm that debugger can access debug information if .debug file is available.

By shipping the debug information in a separate file, downstream
packages (e.g. the Ruby packages) can easily remove the debug
information while packaging libddprof, but it's still very easy to
restore it.

This approach is documented in
<https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html>
and in the `objdump` man pages. Thanks @nsavoire for the tips.

The `strip`'d file retains the `build-id` information.

I've tested with `gdb` and it seems to work:

```
$ gdb libddprof_ffi.so
GNU gdb (Ubuntu 11.1-0ubuntu2) 11.1

Reading symbols from libddprof_ffi.so...
Reading symbols from /working/build-linux-amd64/lib/libddprof_ffi.so.debug...

(gdb) info functions
All defined functions:

File /cargo/registry/src/git.luolix.top-1ecc6299db9ec823/addr2line-0.13.0/src/lib.rs:
966:	static fn addr2line::Function::parse_children<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>();
549:	static fn addr2line::ResUnit::parse_functions<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>();
480:	static fn addr2line::ResUnit::parse_lines<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>();
660:	static fn addr2line::name_attr<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>>();
1162:	static fn addr2line::{{impl}}::for_each_range::{{closure}}<gimli::read::endian_slice::EndianSlice<gimli::endianity::LittleEndian>,closure-0>();

File /cargo/registry/src/git.luolix.top-1ecc6299db9ec823/compiler_builtins-0.1.32/src/macros.rs:
262:	fn compiler_builtins::int::udiv::__udivmodti4();
269:	fn compiler_builtins::int::udiv::__umodti3::__umodti3();
...etc...
```

and if the `.debug` file is deleted:

```
(gdb) info functions
All defined functions:

Non-debugging symbols:
0x0000000000075d00  _init
0x0000000000075d30  __stack_chk_fail@plt
0x0000000000075d40  __tls_get_addr@plt
0x0000000000075d50  __fxstat64@plt
0x0000000000075d60  __gmon_start__@plt
0x0000000000075d70  _Unwind_Resume@plt
0x0000000000075d80  __cxa_finalize@plt
0x0000000000075dc0  deregister_tm_clones
0x0000000000075df0  register_tm_clones
0x0000000000075e30  __do_global_dtors_aux
0x0000000000075e70  frame_dummy
0x0000000000075ea5  std::error::<impl core::convert::From<E> for alloc::boxed::Box<dyn std::error::Error>>::from
0x0000000000075edd  std::error::Error::description
0x0000000000075eea  std::error::Error::cause
...etc...
```

This PR is an alternative to #28, which instead shipped two copies
of the shared library binaries (one `strip`d, and an untouched one).
Copy link
Contributor

@nsavoire nsavoire left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM !

@ivoanjo ivoanjo merged commit c71a321 into main Feb 23, 2022
@ivoanjo ivoanjo deleted the ivoanjo/separate-out-debuginfo branch February 23, 2022 14:50
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants