As we are now shipping a number of snaps in the default install on Ubuntu, the question has come up about how to collect and process crash reports for these applications.
The actual collection of core dumps can probably be done with the existing apport/whoopsie infrastructure (once they learn how to identify the core dump as coming from a snap). But without debug symbols, there is a limit to what we can do to analyse the problem.
I know that there were some discussions about how such a system could work at the October 2016 sprint in The Hague (way back in the Ubuntu Phone days), but am I right in thinking that nothing went beyond those vague plans?
Iāve been thinking a bit about how Snapcraft could be modified to handle this, so here are my thoughts running roughly top down. If no one else is working on this Iāll have a go implementing some of this, so would appreciate feedback on the overall design.
Donāt ship debug symbols in the .snap
As with Debian packages, we donāt want to separate debug symbols from the .snap package: they increase the size of the package while being of little interest to the vast majority of users, and in they could reveal confidential information in the case of proprietary software.
So I propose that the snapcraft snap
command generate a $package_$version_$arch.dbgsym.tar.gz
file alongside $package_$version_$arch.snap
. This tarball would contain a hierarchy matching what is generally found under /usr/lib/debug
. In particular, favouring the .build-id/NN/...debug
layout.
Gathering debug symbols for the archive
We already have code in place to read information out of the ELF files destined for a snap using pyelftools, so it should be fairly trivial to extend it to collect the build ID found in the .note.gnu.build-id
section. It would then iterate through each part searching for debug symbols matching any of the primed build IDs.
Weād probably need some other strategy to handle debug symbols for system libraries that are brought in, not belonging to any part.
Parts generating debug symbols
Part plugins will need to be modified to do two things:
- Configure the build so that debug symbols are generated.
- After the build/install completes, process files in
parts/$part/install
to detach debug symbols and place them inparts/$part/debug
(again resembling the normal/usr/lib/debug
hierarchy).
The first step is likely to be specific to a particular plugin, but most of the logic for the second can likely be shared. Iād probably do this as a utility method that can be called by the plugin, so it can be replaced if there are any exotic plugins.
One other area that will need special attention is stage-packages
: the binaries from these staged packages are already stripped of debug symbols so need to be handled specially. I think something like this should work:
- add the corresponding ddebs sources to the Apt cache used for retrieving stage packages.
- iterate through all the staged packages:
- If a
$name-dbgsym
package exists, download it. - Unpack the dbgsym package and copy the contents of its
/usr/lib/debug
tree to the partās debug tree.
- If a
I think it should be possible to implement something equivalent for RPM packages when Snapcraft grows support for building against a Fedora base.
For edge cases, it would probably also be useful to let a scriptlet produce debug symbols too. Maybe the existing scriptlets are enough if we just let them write to the parts/$part/debug/
directory directly. The main use case I can see for this is collecting debug symbols for the core snap (and other base snaps built in a similar fashion).
This is clearly only one part of a retracing solution. Off the top of my head, weād also need the following:
- some way to the debug symbols associated with particular revisions of a snap uploaded to the store. Maybe the store should eventually be responsible for this, but it doesnāt need to be.
- Apport needs to learn about snaps. In particular:
- when the core file is for an executable found under
/snap
, recognise it as coming from a snap. - Record the name and revision number of the snap the executable comes from.
- For strictly confined snaps, record the name and revision of the base snap in use.
- Check for connected content interface plugs, and record the name and revision of the corresponding slot snaps. This is important for cases like the GNOME platform snap.
- when the core file is for an executable found under
- On the retracing end, somehow retrieve the dbgsym tarballs for each of the snaps referenced in the report. Unpack those tarballs and configure GDB to use these additional sets of debug symbols when retracing the core dump.
Any thoughts on this overall design?