Add subsurface.debug script to help debugging and install it (for Linux only)

This patch adds subsurface.debug script and install it for Linux.
Instead of running subsurface, you can run subsurface.debug which will launch
subsurface as usual, but will monitor subsurface exit and run gdb automatically
if subsurface crashes and it creates a crashlog in $HOME/.

Signed-off-by: Guillaume GARDET <guillaume.gardet@free.fr>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
Guillaume GARDET 2015-10-29 12:21:18 +01:00 committed by Dirk Hohndel
parent 94207fa8d7
commit f451387f8f
2 changed files with 111 additions and 0 deletions

View file

@ -802,6 +802,7 @@ endif()
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
install(DIRECTORY marbledata/maps DESTINATION share/subsurface/data)
install(DIRECTORY marbledata/bitmaps DESTINATION share/subsurface/data)
install(FILES subsurface.debug DESTINATION bin)
install(FILES subsurface.desktop DESTINATION share/applications)
install(FILES subsurface-icon.svg DESTINATION share/icons/hicolor/scalable/apps)
install(DIRECTORY Documentation/images DESTINATION share/subsurface/Documentation)

110
subsurface.debug Executable file
View file

@ -0,0 +1,110 @@
#!/bin/sh
#
# This is a wrapper script (based on kodi/xbmc script) to monitor subsurface and get debug information using GDB when a crash happens.
# Informations are stored in *.log file in CRASHLOG_DIR ($HOME by default)
APP=Subsurface
bin_name=subsurface
SAVED_ARGS="$@"
prefix="/usr"
CRASHLOG_DIR=${CRASHLOG_DIR:-$HOME}
APP_VERSION=$(${prefix}/bin/${bin_name} --version)
command_exists()
{
command -pv $1 >/dev/null 2>&1
}
single_stacktrace()
{
# core filename is either "core.$PID" or "core"
find "$1" -maxdepth $2 -name 'core*' | while read core; do
LC_ALL=C gdb --core="$core" --batch 2> /dev/null | grep -q "^Core was generated by \`${prefix}/bin/${bin_name}" || continue
echo "=====> Core file: "$core" ($(stat -c%y "$core"))" >> $FILE
echo " =========================================" >> $FILE
gdb "${prefix}/bin/${bin_name}" --core="$core" --batch -ex "thread apply all bt" 2> /dev/null >> $FILE
rm -f "$core"
done
}
print_crash_report()
{
FILE="$CRASHLOG_DIR/${bin_name}_crashlog-`date +%Y%m%d_%H%M%S`.log"
echo "############## $APP CRASH LOG ###############" >> $FILE
echo >> $FILE
echo "################ SYSTEM INFO ################" >> $FILE
echo -n " Date: " >> $FILE
LC_ALL=C date >> $FILE
echo " $APP Options: $SAVED_ARGS" >> $FILE
echo " $APP version: $APP_VERSION" >> $FILE
echo -n " Arch: " >> $FILE
uname -m >> $FILE
echo -n " Kernel: " >> $FILE
uname -rvs >> $FILE
echo -n " Release: " >> $FILE
if [ -f /etc/os-release ]; then
. /etc/os-release
echo $NAME $VERSION >> $FILE
elif command_exists lsb_release; then
echo >> $FILE
lsb_release -a 2> /dev/null | sed -e 's/^/ /' >> $FILE
else
echo "lsb_release not available" >> $FILE
fi
echo "############## END SYSTEM INFO ##############" >> $FILE
echo >> $FILE
echo "############### STACK TRACE #################" >> $FILE
if command_exists gdb; then
# TODO: systemd needs more test (systemd-coredumpctl exist on openSUSE 13.1 but does not find any core)
# if command_exists systemd-coredumpctl; then
# systemd-coredumpctl dump -o core ${prefix}/bin/${bin_name} > /dev/null 2>&1
# elif command_exists coredumpctl; then
# coredumpctl dump -o core ${prefix}/bin/${bin_name} > /dev/null 2>&1
# fi
# Find in current directory
single_stacktrace "$PWD" 1
# Find in plugins directories
if [ $KODI_HOME ]; then
BASEDIR=$KODI_HOME
else
BASEDIR="$LIBDIR/${bin_name}/"
fi
single_stacktrace "$BASEDIR" 5
# find in userdata dir
single_stacktrace "$HOME" 5
# try /proc/sys/kernel/core_pattern
[ -d "$(dirname $(cat /proc/sys/kernel/core_pattern))" ] && single_stacktrace "$(dirname $(cat /proc/sys/kernel/core_pattern))" 1
else
echo "gdb not installed, can't get stack trace." >> $FILE
fi
echo "############# END STACK TRACE ###############" >> $FILE
echo >> $FILE
echo "############ END $APP CRASH LOG #############" >> $FILE
echo "Crash report available at $FILE"
}
if command_exists gdb; then
# Output warning in case ulimit is unsupported by shell
eval ulimit -c unlimited
if [ ! $? = "0" ]; then
echo "${bin_name}: ulimit is unsupported by this shell" 1>&2
fi
fi
LOOP=1
while [ $(( $LOOP )) = "1" ]
do
LOOP=0
"${prefix}/bin/${bin_name}" $SAVED_ARGS
RET=$?
if [ $(( $RET == 65 )) = "1" ]
then # User requested to restart app
LOOP=1
elif [ $(( ($RET >= 131 && $RET <= 136) || $RET == 139 )) = "1" ]
then # Crashed with core dump
print_crash_report
fi
# echo "RET = $RET"
done
exit $RET