Debugging Information¶
UDB uses debugging information to interpret the memory and CPU state of your process and present a symbolic view of your application. The most commonly used debugging data format for compiled Linux executables is the DWARF standard.
Separate debug information files¶
The debug information can be stored inside the executable or libraries themselves or in separate debug files. UDB and LiveRecorder look for debug information files and save them into the Undo recording so that they are available when replaying with UDB regardless of which machine the recording is loaded on.
Custom debug file directories¶
By default, UDB and LiveRecorder will look for debug information files in the
standard /usr/lib/debug directory. Custom debug file directories can be
specified in LiveRecorder by setting the UNDO_debug_file_directories
environment variable, and in UDB the by setting debug-file-directory, to a
colon-separated list of paths (which in UDB must contain /usr/lib/debug if
you still want to search this).
Supported schemes for separate debug files¶
Being able to save debug information files depends on the files being stored and referenced in a standard way. There are several ways to do this, and UDB and LiveRecorder aims to support all of them.
Debuglink¶
This debug information scheme embeds a reference to a debug file within a
.gnu.debuglink section inside the executable or shared object.
This reference can be added to the executable or shared object by the objcopy program:
objcopy --add-gnu-debuglink=/path/to/debug-file /path/to/executable
UDB and LiveRecorder will look for the file referenced by the debuglink in the following places:
The directory of the executable or shared object.
A subdirectory named
.debugin the directory of the executable or shared object.In any of the configured Custom debug file directories concatenated with the directory of the executable or shared object.
For example, if the executable is /usr/bin/ls, and the Custom debug file directories are configured as the value /home/user/debuginfo, then
LiveRecorder and UDB look for these files, and if they exist, include them in
the Undo recording:
/usr/bin/ls.debug/usr/bin/.debug/ls.debug/usr/lib/debug/usr/bin/ls.debug/home/user/debuginfo/usr/bin/ls.debug
Build ID¶
This debug information scheme embeds a unique Build ID hash in the executable or
shared object. This is used to look up the corresponding debug information file.
Build ID files are stored in the standard location /usr/lib/debug/.build-id,
with filenames corresponding to their Build ID.
The Build ID uniquely identifies each executable or shared object. It is
generated by the linker program and is stored in a .note.gnu.build-id ELF
section in the executable. The readelf program can be used to inspect
the Build ID of an executable or shared object:
readelf -n /path/to/executable
For each of the Custom debug file directories configured UDB and LiveRecorder
will look in the .build-id subdirectory for a file in a directory with the
first two hexadecimal characters of the Build ID, and a file with the rest of
the Build ID with a .debug extension.
For example, if the Build ID is 039f6f2f91837cfe6b31187b38ca1113a50c4aea and
the Custom debug file directories are configured as the value
/home/user/debuginfo" then UDB and LiveRecorder will look for:
/usr/lib/debug/.build-id/03/9f6f2f91837cfe6b31187b38ca1113a50c4aea.debug/home/user/debuginfo/.build-id/03/9f6f2f91837cfe6b31187b38ca1113a50c4aea.debug
Split DWARF¶
Some compilers support a feature called “split DWARF” which separates as
much debug information as possible into DWARF object (DWO) files with .dwo
extensions. In contrast to the Debuglink debug information scheme, where
the reference is created after the linking step, and the Build ID debug
information scheme, where the reference is created during the linking step, the
DWO files and references are created during the compilation step.
DWO files can be created by passing the -gsplit-dwarf option to GCC or
Clang. For more information see Reduce binary size and compile time with split DWARF.
Some DWARF information is retained in the original executable, including the
DW_AT_dwo_name and DW_AT_dwo_id attributes which are used to look up the
separate DWO files. If relative path are used they are appended to the compilation
directory which stored in the DW_AT_comp_dir attribute.
These paths are searched for under the custom debug file directories. For example,
if DW_AT_dwo_name is /home/build/ls.dwo and the Custom debug file directories
are configured as the value /home/user/debuginfo", then UDB and LiveRecorder will look for:
/home/build/ls.dwo/user/lib/debug/home/build/ls.dwo/home/user/debuginfo/home/build/ls.dwo/user/lib/debug/ls.dwo/home/user/debuginfo/ls.dwo
With a DW_AT_dwo_name of build/ls.dwo, DWO_AT_comp_dir of
/home/comp and the Custom debug file directories are configured as the
value /home/user/debuginfo", UDB and LiveRecorder will look for:
/home/comp/build/ls.dwo/usr/lib/debug/build/ls.dwo/home/user/debuginfo/build/ls.dwo/user/lib/debug/ls.dwo/home/user/debuginfo/ls.dwo
DWARF package files¶
When using the “Split DWARF” approach, the compiler generates a DWO file for
each compilation unit. The “DWARF package file” is an approach where multiple
DWO files are combined into a single DWARF package (DWP) file for each
executable. UDB and LiveRecorder will save DWP files that are stored in the same
directory as the original executable or in one of the Custom debug file directories,
and have the same name as the original executable plus a .dwp extension.
DWARF compression files: debugaltlink¶
The DWARF compression tool can be used to
extract duplicate debugging information from multiple executables and shared
libraries into a shared .dwz ELF file. The dwz program removes
the original, redundant debugging information from the original executables and
shared libraries and adds a .gnu_debugaltlink ELF section containing:
The path to the
.dwzfile.A Build ID corresponding to the
.dwzfile.
UDB and LiveRecorder use the .gnu_debugaltlink section to find the separate .dwz file:
If the contained path is absolute it is checked directly.
If the contained path is relative it is appended to the directory of the executable or shared library and then checked.
If the contained path contains a
/.dwz/component, then the path leading up to the component is replaced with each of the configured Custom debug file directories.The Build ID is looked up in the same way as a regular Build ID.
For example, if the .gnu_debugaltlink section contains a path with the value
/files/debug/.dwz/x86_64-linux-gnu/ls.debug and a Build ID with the value
039f6f2f91837cfe6b31187b38ca1113a50c4aea, and the Custom debug file directories are configured with the value /home/user/debuginfo, then UDB
and LiveRecorder will look for:
/files/debug/.dwz/x86_64-linux-gnu/ls.debug/usr/lib/debug/.dwz/x86_64-linux-gnu/ls.debug/home/user/debuginfo/.dwz/x86_64-linux-gnu/ls.debug/usr/lib/debug/.build-id/03/9f6f2f91837cfe6b31187b38ca1113a50c4aea.debug/home/user/debuginfo/.build-id/03/9f6f2f91837cfe6b31187b38ca1113a50c4aea.debug
Unsupported schemes¶
UDB and LiveRecorder do not currently support the DWARF-5 debug information
scheme, where a .debug_sup ELF section is used to refer to the debug
information file.