How to make a Debian debug package

Introduction

Application developers should provide debug packages corresponding to their application packages. This document shows how to do that.

Debian debug packages contain debug symbol files that debuggers (like gdb) will automatically load when the application is debugged.

On ARM environment the debugger can not do backtracing nor show correct function names without debugging symbols making it thus impossible to debug optimized binaries or libraries. All libraries in the device are optimized.

In X86 target debugging can be done without debug symbols.

If the package maintainer provides no debug package then the other developers in the community need to spend extra time and effort to recompile the application (or the library) with the debugging symbols. This extra (time consuming) step can be simply eliminated by the package maintainer by providing a ready compiled debug package.

This document covers creating a Debian debug package from the maemo/Scratchbox point of view.

It is the package maintainers role and decision to create and provide a debug package for her application or library. This means that you as the package owner are responsible to modify the debian package configurations so that the dpkg-buildpackage tool will produce the additional dbg-package.

If you are a maintainer of a library or binary package it is strongly recommended to create a corresponding debug package. This is needed by anybody wanting to either debug or profile your software or something using it.

Creating DBG packages

Steps to create a debian DBG package are:

  • 1. Clean up any previous dbg configurations from your package

    If your package already provides the debugging symbols the "hard, old way" then you should clean these configurations first.

    If you use dh_strip --dbg-package option in debian/rules file then it's not necessary to build or copy anything to the -dbg package build directory anymore. Check your packages debian/rules file and remove all lines that have statements to create dbg packages.

    If you have any files named debian/*-dbg.* then just remove these files. These were required with the old way to use dh_strip.

    The following steps are the only ones needed to create the debug packages with newer versions of dh_strip.

    After you have cleaned up any previous dbg configurations from your debian files move to step 2.

  • 2. Define DBG package(s)

    For every package listed in your debian/control file which contains libraries or binaries you need to add corresponding <package>-dbg entry. If you have debian/control.in then modify that instead.

    Make the debug package(s) to depend from the corresponding binary/library package. Here is an example:

    
    .
    . other package definitions above
    .
    
    Package: libgtk2.0-0-dbg
    Section: libdevel
    Architecture: any
    Depends: libgtk2.0-0 (= ${Source-Version})
    Description: Debug symbols for the Gtk library
    
    

    If the package contains binaries instead of libraries, the section should be 'devel'.

    Note that the new -dbg package may have a different name from the old style debug package (for example libgtk2.0-0-dbg, not libgtk2.0-dbg). If there are earlier (old style) debug packages in the repositories the new debug package should replace/conflict with the old one.

  • 3. Add option -g to CFLAGS

    Make sure you have set option -g in CFLAGS in the debian/rules file and that this option is effective and always enabled. Otherwise the debug package doesn't contain the required debug symbols.

    For example use a line like this for CFLAGS

    
    CFLAGS = -Wall -g
    
    
  • 4. Use dh_strip

    You can either provide all debugging information for your package or just a minimal debugging information required to debug something else using your library.

    You want to select the latter option only if you want to reveal as little of your code as possible (for example) for contract reasons.

    • 4.1 Providing all debug information in your dbg package.

      Add the dh_strip command to binary-arch target in the debian/rules file like this:

      
      dh_strip --dbg-package=<package1>  [--dbg-package=<package2> ...]
      
      

      For example:

      
      dh_strip --dbg-package=libgtk2.0-0
      
      

      This separates debug symbols from <packageN> and puts them into <package>-dbg.

      If you're using cdbs instead of debhelper (dh_* commands) in your debian/rules file, use this instead:

      
      DEB_DH_STRIP_ARGS := --dbg-package=<package1> ...
      
      
      dh_strip has a different syntax for --dbg-package at compatibility level 5, with that you need to postfix the package name given to --dbg-package with -dbg i.e. use -dbg-package=<package>-dbg. However, with lower compatibility levels (default is 1) it SHOULD not be added!

      In addition, note that compat levels 2 and below are deprecated.

      Level 5 is not supported by the debhelper version provided by Scratchbox debian-devkit version 1.0.7 or earlier.

    • 4.2 Providing just minimal debug information

      In case you don't want to reveal all information about your binary (e.g. for contract reasons), you can provide debug symbol file just with the .debug_frame section (which is minimal information needed by Gdb to show working backtraces in ARM environment). In addition to information provided by the binary file, it will reveal only static function names and the number of function arguments.

      To do this, replace the above dh_strip line in debian/rules file binary-arch target with:

      
      chmod +x $(shell pwd)/debian/wrapper
      export PATH=$(shell pwd)/debian/wrapper:$$PATH; \
      dh_strip  --dbg-package=<package1> [--dbg-package=<package2> ...]
      
      

      Note that the wrapper script is set executable because the dpkg-source does not preserve the exec permissions.

      Store the following wrapper script as debian/wrapper/objcopy:

      
      #!/bin/sh
      #
      
      case " $* " in
        *" --only-keep-debug "*)
          exec /usr/bin/objcopy -R .debug_info -R .debug_aranges \
               -R .debug_pubnames -R .debug_abbrev -R .debug_line \
      	 -R .debug_str -R .debug_ranges -R .comment -R .note "$@"
          ;;
      esac
      exec /usr/bin/objcopy "$@"
      
      

      With this dh_strip will use objcopy through this wrapper (i.e. remove the other debug sections).

  • 5. Verify the package(s)

    Update the Debian changelog with dch -i and build the package with dpkg-buildpackage -rfakeroot. This will create new Debian source package (dsc + diff) and binary package(s) which you can install on the target for additional testing.

See also dh_strip (1) and debhelper (7) manual pages for details about the helper scripts.

If the package has any function(s) that have the noreturn GCC attribute, you need to make sure that the object(s) containing those are compiled with -fno-omit-frame-pointer (or remove the noreturn attribute). This is needed for backtraces containing them to be debuggable when the binaries are optimized, the debug symbols are not enough for them. By default GCC omits frame pointer when code is optimized.

Using and installing DBG packages

The debug packages are easy to use, just apt-get install them and on target gdb will load the new style debug symbol files (installed to subdirectories under /usr/lib/debug/) automatically.

Inside Scratchbox, debuggers and profilers will search for the debug symbol files under scratchbox target directory under /usr/lib/debug, so a target directory needs to be linked under it.


mkdir /usr/lib/debug
cd /usr/lib/debug
mkdir targets
ln -s /usr/lib/debug targets/$(sh -c '. /targets/links/scratchbox.config;echo $SBOX_TARGET_NAME') 

	

The reason for this is that realpath on libraries and binaries inside Scratchbox returns /scratchbox/targets/.../usr/lib/... instead of just normal /usr/lib/....

Installing the maemo-debug-scripts package does this link automatically.

And for thread debugging to work, you need to install libc6-dbg package and gdb package, the Scratchbox provided host gdb doesn't work with threads (or ARM core dumps). To use the native gdb in Scratchbox, you need to start gdb the following way:


SBOX_REDIRECT_IGNORE=/usr/bin/gdb /usr/bin/gdb /usr/bin/my-binary

      

maemo-debug-scripts package provides native-gdb script for this.

For gdb to find old style debug symbol files (installed directly into /usr/lib/debug/) you need to use LD_LIBRARY_PATH or load them manually in gdb.

Files in these old style debug symbol files contain both the binary and debug symbol sections, so they are also larger than the new style debug symbols which dh_strip instructions above will create.



Improve this page