Google Summer of Code 2016 is now over. We have polished the code and documentation and submitted the final term evaluation on 23rd of August 2016. The mentors evaluated us in the following week.
If you are impatient (and this time impatience is definitely a virtue!) please take a look to all The NetBSD Foundation GSoC 2016 projects' code submissions!
In part 1 we have learned what happens under the hood when we split debugging symbols: how debugging information is stored/stripped off, the relevant ELF sections involved, various tools to dump that information, etc..
In particular, we have studied what happens on NetBSD when we set the
MKDEBUG* flags.
With this background we can finally try to implement this functionality in the
pkgsrc infrastructure. In this blog post we
will first give a practical look at PKG_DEBUGDATA and then we
will analyze the code that I have written in the first mid-term of the GSoC to
accomplish that.
PKG_DEBUGDATA in actionBefore digging in the implementation of debugdata functionality let's see what it produces!
In part 1
we took as example a very simple program that just prints out the lyrics of
Ten Green Bottles song. After packaging it as
local/green-bottles
let's just build it without any special pkgsrc system variables set:
$ cd pkgsrc/local/green-bottles $ make install [...] $ green-bottles ten green bottles hanging on the wall [...] $ pkg_info -L green-bottles Information for green-bottles-0: Files: /usr/pkg/bin/green-bottles $ gdb `which green-bottles` GNU gdb (GDB) 7.10.1 Copyright (C) 2015 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> [...] Reading symbols from /usr/pkg/bin/green-bottles...(no debugging symbols found)...done. (gdb) quit
That's expected because we did not set any special CFLAGS nor
INSTALL_UNSTRIPPED.
Before setting PKG_DEBUGDATA to "yes" let's inspect its
documentation via the help target:
$ make help topic=PKG_DEBUGDATA ===> mk/bsd.debugdata.mk (keywords: INSTALL_UNSTRIPPED PKG_DEBUGLEVEL PKG_DEBUGDATA debug): # This Makefile fragment is included by bsd.pkg.mk and implements the # logic needed to strip debug symbols off the program/libraries. # # User-settable variables: # # PKG_DEBUGDATA # If "yes", install stripped debug symbols for all programs and shared # libraries. Please notice that if it is defined INSTALL_UNSTRIPPED will # be also defined internally. # # PKG_DEBUGLEVEL # Used to control the granularity of the debug information. Can be # "small", "default", "detailed". # TODO: the name of this variable should be changed because it can be # TODO: easily confused with PKG_DEBUG_LEVEL! # # See also: # INSTALL_UNSTRIPPED #
Now that we have finally an idea of what PKG_DEBUGDATA does, let's
set it and reinstall the green-bottles package:
$ make clean deinstall [...] $ PKG_DEBUGDATA=yes make install [...] ===> Installing for green-bottles-0 [...] => Stripping debug symbols => Installing debug data [...] => Checking for missing debug data in green-bottles-0 [...]
Apart from the various phases we can see three extra messages that are now printed out: stripping of debug symbols, installing of debug data and a check for missing debug data.
If we inspect the files installed we can now also see
green-bottles.debug:
$ pkg_info -L green-bottles Information for green-bottles-0: Files: /usr/pkg/bin/green-bottles.debug /usr/pkg/bin/green-bottles
Indeed if we now try to run it through gdb(1):
$ gdb `which green-bottles`
GNU gdb (GDB) 7.10.1
Copyright (C) 2015 Free Software Foundation, Inc.
[...]
Reading symbols from /usr/pkg/bin/green-bottles...Reading symbols from /usr/pkg/bin/green-bottles.debug...done.
done.
(gdb) b main
Breakpoint 1 at 0xad0: file green-bottles.c, line 29.
(gdb) run
Starting program: /usr/pkg/bin/green-bottles
Breakpoint 1, main () at green-bottles.c:29
29 {
(gdb)
[...]
green-bottles was installed as usual without requiring any changes
from MAINTAINERs, in fact the various .debug files
are generated, installed and added to the PLIST dynamically.
mk/bsd.debugdata.mk and mk/check/check-debugdata.mk implementation
All the functionalities that implement stripping of the debug data from
installed programs and libraries are implemented entirely in
bsd.debugdata.mk.
check/check-debugdata.mk
checks that all programs and libraries have the debug
data correctly stripped into their corresponding *.debug files.
mk/bsd.debugdata.mk
The
first 23 lines of bsd.debugdata.mk contain a comment that is also
accessible via the help
target. In particular it describes all the user-settable variables:
PKG_DEBUGDATA: if "yes" it turns on debugdata functionality to
generate the *.debug files and then install them as part of the
package.
PKG_DEBUGLEVEL: useful to control the granularity of the debug
information, i.e. the -g level flag passed to the compiler. It can
be "small", "default" and "detailed".
Then _VARGROUPS and _USER_VARS.<vargroup>
are set accordingly. These are used by the show-all target (if you
are more curious regarding that please just try make show-all and/or
give a look to
mk/misc/show.mk).
After various definitions of some used variables (should be self-explainable)
_FIND_DEBUGGABLEDATA_ERE is defined as an Extended Regular
Expression that is used to match potential files that can be stripped.
_FIND_DEBUGGABLEDATA_ERE is then used to limit the file list
generated via
_FIND_DEBUGGABLEDATA_FILELIST_CMD
Lines 63-86 pass the appropriate debug flags and debug level to the compiler.
Then _PLIST_DEBUGDATA is added to the PLIST_SRC_DFLT
variable. PLIST_SRC_DFLT contains all the default
PLISTs that
usually resides in pkgsrc/category/PLIST* (e.g. PLIST,
PLIST.common, PLIST.NetBSD, etc.). If you are more
interested in how it works, please give a look to
mk/plist/plist.mk.
In this way all the *.debug files listed in
_PLIST_DEBUGDATA are dynamically appended to the package
PLIST.
In lines
90-111 generate-strip-debugdata target is defined. It
basically just does the operations we have explored in
part 1
with little adjustments for pkgsrc:
objcopy
--only-keep-debug program|library program.debug|library.debug is invoked
in order to populate the .debug file.
objcopy
--strip-debug -p -R .gnu_debuglink
--add-gnu-debuglink=program.debug|library.debug program|library is
invoked to delete the debug information from the current file (program or
library) and to add the
.gnu_debuglink ELF section to it so that the debugger knows where
to pick the corresponding .debug file.
.debug path and filename to the
_PLIST_DEBUGDATA file.
To accomplish that RUN is used to run all shell commands without
printing them. Please note that when RUN is used all shell commands
should be terminated with a semicolon. For more information regarding
RUN please take a look at make help topic=RUN.
In lines
113-122 install-strip-debugdata is defined. It just installs all
*.debug files via INSTALL_DATA.
install-strip-debugdata target will then be invoked after the
post-install phase.
mk/check/check-debugdata.mkFirst 26 lines of check-debugdata.mk contain a comment for the pkgsrc online documentation. It describes the following user-settable variables:
CHECK_DEBUGDATA: if "yes" it enables debugdata checks (by default
most checks are usually enabled only if PKG_DEVELOPER is "yes")
...and the following package-settable variables:
CHECK_DEBUGDATA_SKIP: list of shell patterns that should be
excluded from the check.
CHECK_DEBUGDATA_SUPPORTED: whether the check should be enabled for
the package or not.
Like what it was done for
bsd.debugdata.mk, _VARGROUPS and
_{USER,PKG}_VARS.check-debugdata are defined accordingly.
Similarly to what was done for _FIND_DEBUGGABLEDATA_ERE and
_FIND_DEBUGGABLEDATA_FILELIST_CMD in
bsd.debugdata.mk,
_CHECK_DEBUGDATA_ERE and
_CHECK_DEBUGDATA_FILELIST_CMD
are defined.
In lines
54-103 _check-debugdata target is defined.
_check-debugdata performs the following checks, respectively:
.gnu_debuglink ELF section.
.debug file of the program/library is
readable.
.debug file does not contain a
.debug_info ELF section.
mk/*
In order to instruct pkgsrc to pick up bsd.debugdata.mk and
checks/check-debugdata.mk, nothing intrusive though:
.include "bsd.debugdata.mk" in bsd.pkg.mk.
TOOLS_PLATFORM.objcopy
and
TOOLS_PLATFORM.objdump
to mk/tools/tools.NetBSD.mk
(other OPSYSs will also needed to be adjusted similarly)
CHECK_DEBUGDATA_SUPPORTED to
check/bsd.check-vars.mk.
.include "check-debugdata.mk" in
check/bsd.check.mk.
In this blog post we have learned what PKG_DEBUGDATA does via a
practical example.
Then we have examinated how bsd.debugdata.mk and
checks/check-debugdata.mk are implemented.
PKG_DEBUGDATA is completely agnostic if a package uses
GNU configure, cmake, etc., and it is expected to work without any changes.
I have only tested it with simple packages also containing libraries and the
ones that uses libtool but I have still not tested it in the wild and some minor
adjustements can be probably needed.
Thanks again to Google for organizing Google Summer of Code, The NetBSD Foundation and in particular my mentors David Maxwell, Jöerg Sonnenberger, Taylor R. Campbell, Thomas Klausner and William J. Coldwell.
/usr/share/doc/ref1/make/ in PS and text format)