Debug Symbol Pakcages

Debug Symbol Packages

  1. Create an /etc/apt/sources.list.d/ddebs.list by running the following line at a terminal:

    1
    2
    3
    4
    5
    # for ubuntu
    echo "deb http://ddebs.ubuntu.com $(lsb_release -cs) main restricted universe multiverse
    deb http://ddebs.ubuntu.com $(lsb_release -cs)-updates main restricted universe multiverse
    deb http://ddebs.ubuntu.com $(lsb_release -cs)-proposed main restricted universe multiverse" | \
    sudo tee -a /etc/apt/sources.list.d/ddebs.list
    1
    2
    3
    4
    5
    6
    7
    8
    # for debian
    deb http://deb.debian.org/debian-debug/ stable-debug main
    deb http://deb.debian.org/debian-debug/ proposed-updates-debug main
    deb http://deb.debian.org/debian-debug/ stretch-backports-debug main
    deb http://deb.debian.org/debian-debug/ testing-debug main
    deb http://deb.debian.org/debian-debug/ testing-proposed-updates-debug main
    deb http://deb.debian.org/debian-debug/ unstable-debug main
    deb http://deb.debian.org/debian-debug/ experimental-debug main
  2. Import the debug symbol archive signing key from the Ubuntu server:

    1
    2
    $ sudo apt install ubuntu-dbgsym-keyring   
    $ sudo apt update
  3. Install debug packages

    1
    $ sudo apt install xxx-dbgsym
  4. Automatic resolution

  • 使用debian-goodies获取需要安装的所有dbgsym包

    1
    2
    apt install debian-goodies
    find-dbgsym-packages [core_path|running_pid|binary_path]
  • 或者通过以下脚本(此脚本年久失修,需要更新)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    #!/bin/bash -x
    progname=`basename "$0"`

    explain() {
    cat << EOF
    Usage: $progname [-adt] [-p pid] | [exectable]

    You must specify a pid (-p) or an executable name/path.

    This scripts list the dbug symbols packages you need to install for a complete dump of the give executable. Already installed symbols packages are not shown.

    Options are:
    -p pid uses the running process with the given pid to get the list.
    If specified, you may omit the executable name.
    -a show all the required symbol packages (not only the not-installed
    ones)
    -d prefer XXX-dbg symbol packages over XXX-dbgsym ones
    -t terse: print the packages names only (no package description).
    Useful to pass output directly to apt-get install.

    NOTE: in some cases $progname may report already installed
    packages. This currently happens with binaries using libpthread.so as
    libc6-i686-dbgsym apparently doesn't contain debug symbols for it.

    To examine a running server process by pid, you will need to run this script
    using sudo.
    EOF
    exit -1
    }

    all=false
    preferred="dbgsym dbg"
    debug=false
    terse=false
    pid=
    while getopts :adgp:t opt; do
    case $opt in
    a)
    all=true
    ;;
    d)
    preferred="dbg dbgsym"
    ;;
    g)
    debug=true
    ;;
    p)
    pid="$OPTARG"
    binary=$(readlink /proc/$pid/exe)
    [ -z "$binary" ]&& echo "Unable to get binary path for pid $pid" && exit -1
    t)
    terse=true
    ;;
    \?)
    explain
    ;;
    esac
    done

    if [ -z "$binary" ]; then
    shift $(( $OPTIND - 1 ))
    [ $# -ne 1 ] && explain
    binary="$1"
    [ ! -x "$binary" -a `basename @"$binary"` = @"$binary" -a -n "`which $binary`" ] && binary=`which $binary`
    fi

    find-debug() {
    while read i; do
    for ext in $preferred; do
    i=$(echo "$i"|cut -f 1 -d:) #remove the architecture suffix
    apt-cache search "^$i-$ext\$"
    done |head -1
    done
    }

    if [ ! -z "$pid" ]; then
    Args="--pid=$pid"
    else
    Args="$binary"
    fi

    echo q| gdb "$Args" | \
    grep 'Reading symbols from '| \
    if $all; then cat; else grep 'no debugging symbols found'; fi | \
    sed -e 's/^Reading symbols from \(.*\)\.\.\.\((\|Reading \).*$/\1/' | \
    while read i; do \
    #dpkg -S "$i" |while read j; do if $debug; then echo '!' $i '-->' $j 1>&2; fi; echo $j; done
    ( if ! dpkg -S "$i" 2>/dev/null; then [ -L "$i" ] && dpkg -S `readlink "$i"`; fi ) | \
    while read j; do if $debug; then echo '!' $i '-->' $j 1>&2; fi; echo $j; done \
    done| sed -e 's/^\(.*\): .*$/\1/' | sort -u | \
    find-debug | if $terse; then sed -e 's/ - .*$//'; else cat; fi |sort -u
  1. Set generate core dump:

    1
    2
    3
    4
    5
    ulimit -c unlimited
    # Ubuntu set /proc/sys/kernel/core_pattern to 'apport /usr/share/apport/apport %p %s %c %p', so stop it first.
    sudo service apport stop
    # Set the location of coredump file.
    sudo sysctl -w kernel.core_pattern=/tmp/core-%e.%p.%h.%t

    or set these properties permanently:

    1
    2
    3
    4
    5
    6
    # edit /etc/security/limits.conf
    * soft core unlimited
    root soft core unlimited
    # edit /etc/sysctl.conf and make it effective
    kernle.core_pattern=/tmp/core-%e.%p.%h.%t
    sysctl -p

You can install systemd-coredump to control dump file deeply.

  1. gdb ./a.out core

Debian

https://wiki.debian.org/AutomaticDebugPackages

Principle

/usr/lib/.build-id contains the main build-id files for installed packages.

Debug info packages are used in many distributions to provide a way for users to install debugging information when necessary, without bloating binaries for everyone. When a program or library is built and linked, it can be built with debugging information, which debuggers can then use to map locations in the binary with locations in its source code; but this information takes up a lot of room. So debugging information is typically stripped from binaries before they’re packaged. In recent years, strip and objcopy have been enhanced so that debugging information can be extracted and stored separately — that’s how debug info packages are built. All that’s needed then is some way of ensuring that a binary and its debug information correspond, and that’s where build ids come in — they are unique identifiers calculated by ld (look for --build-id there) over the significant portions of a binary. “Main build-id files” are symlinks from a build id to the corresponding binary or debug info file; they allow two-way mappings to be implemented, so that core dumps can be usefully debugged (there’s a link from binaries to their build ids in the binaries themselves, in the .gnu_debuglink section). You’ll find a detailed explanation of the reasoning behind all this in the Fedora build-id feature description.

1
2
3
4
5
6
7
8
9
10
11
12
$ readelf -S ukui-indicators //没啥用
[28] .gnu_debuglink PROGBITS 0000000000000000 0001b0f4
0000000000000034 0000000000000000 0 0 4

$ dpkg -L ukui-indicators-dbgsym
/usr/lib/debug/.build-id/04/165df8cff97ce4a70ce9cb3738812bcee72c07.debug

$ readelf -all ukui-indicators
Displaying notes found in: .note.gnu.build-id
所有者 Data size Description
GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring)
Build ID: 04165df8cff97ce4a70ce9cb3738812bcee72c07