summaryrefslogtreecommitdiff
path: root/bin/extra/gdbcore
blob: 667db3e299bd866da0d465305571d351c9bc2200 (plain)
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
#!/bin/sh

# Open the latest core file for program with gdb
# RETURN VALUES
# 0 - success
# 1 - if the program was not found or not executable
# 2 - if the user did aborted
# 3 - zstd failed
# 4 - wrong usage

if [ "$#" -lt 1 ]; then
    >&2 printf 'usage: gdbcore [-r] <program>\n'
fi

if [ "$1" = "-r" ]; then
    recent=1
    shift
fi

prog="$1"
if [ ! -x "$prog" ]; then
    prog="$(which "$prog" 2>/dev/null)"
    [ -x "$prog" ] || exit 1
fi

# Directory where corefiles are located
coredir=/var/lib/systemd/coredump
# Temporary file listing core files location, later used as location for the corefile
tmp="$(mktemp)"


if [ "$recent" ]; then
    file="$(find "$coredir" -name "core.${prog##*/}*" -printf '%Ts %f\n' |
        sort -n -r | head -n 1 |
        cut -f 2- -d' ')"
    corefile="$coredir"/"$file"
else

    find "$coredir" -name "core.${prog##*/}*" -printf '%f %TF %TT\n' > "$tmp"

    choice="$(sed \
        -e 's/\.[0-9]\+$//' \
        -e 's/^core\.//' \
        -e 's/\.[0-9]\+\.[0-9a-f]\+\.[0-9]\+\.[0-9]\+\.zst / /' \
        "$tmp" |
        awk '{print NR ".", "[" $3,$2"]", $1}' | 
        sort -r -k 3 -k 2 |
        fzf -0 --with-nth=2..)"
    if [ -z "$choice" ]; then
        rm "$tmp"
        exit 2
    fi

    nr="${choice%%.*}"
    line="$(sed -n "${nr}p" "$tmp")"
    corefile="$coredir"/"${line%% *}"
fi

if [ ! -f "$corefile" ]; then
    rm -f "$tmp"
    exit 1
fi

if ! zstd -d "$corefile" -f -o "$tmp" 2>/dev/null; then
    rm -f "$tmp"
    exit 3
fi

gdb -q "$prog" "$tmp"

rm -f "$tmp"