mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-04 12:12:48 +00:00
ast_coredumper: Add ability to use directory other than /tmp
The OUTPUTDIR environment variable can now be set either in the environment itself or in ast_debug_tools.conf. If set, it's used for all work products instead of /tmp. Also added the --tarball-config option that includes the contents of /etc/asterisk when either --tarball-coredumps or --tarball-results are used. Change-Id: I66b2553319df61caea5b313d084f51978f730b4c
This commit is contained in:
@@ -20,6 +20,12 @@
|
|||||||
# anyway.
|
# anyway.
|
||||||
COREDUMPS=(/tmp/core[-._]asterisk!(*.txt) /tmp/core[-._]$(hostname)!(*.txt))
|
COREDUMPS=(/tmp/core[-._]asterisk!(*.txt) /tmp/core[-._]$(hostname)!(*.txt))
|
||||||
|
|
||||||
|
# The directory to contain output files and work directories.
|
||||||
|
# For output from existing core files, the default is the
|
||||||
|
# directory that the core file is found in. For core files
|
||||||
|
# produced from a running process, the default is /tmp.
|
||||||
|
OUTPUTDIR=/some/directory
|
||||||
|
|
||||||
# Date command for the "running" coredump and tarballs.
|
# Date command for the "running" coredump and tarballs.
|
||||||
# DATEFORMAT will be executed to get the timestamp.
|
# DATEFORMAT will be executed to get the timestamp.
|
||||||
# Don't put quotes around the format string or they'll be
|
# Don't put quotes around the format string or they'll be
|
||||||
|
@@ -15,7 +15,7 @@ SYNOPSIS
|
|||||||
$prog [ --help ] [ --running | --RUNNING ] [ --latest ]
|
$prog [ --help ] [ --running | --RUNNING ] [ --latest ]
|
||||||
[ --tarball-coredumps ] [ --delete-coredumps-after ]
|
[ --tarball-coredumps ] [ --delete-coredumps-after ]
|
||||||
[ --tarball-results ] [ --delete-results-after ]
|
[ --tarball-results ] [ --delete-results-after ]
|
||||||
[ --tarball-uniqueid="<uniqueid>" ]
|
[ --tarball-config ] [ --tarball-uniqueid="<uniqueid>" ]
|
||||||
[ --no-default-search ] [ --append-coredumps ]
|
[ --no-default-search ] [ --append-coredumps ]
|
||||||
[ --asterisk-bin="path" ]
|
[ --asterisk-bin="path" ]
|
||||||
[ <coredump> | <pattern> ... ]
|
[ <coredump> | <pattern> ... ]
|
||||||
@@ -51,7 +51,8 @@ DESCRIPTION
|
|||||||
Create a coredump from the running asterisk instance and
|
Create a coredump from the running asterisk instance and
|
||||||
process it along with any other coredumps found (if any).
|
process it along with any other coredumps found (if any).
|
||||||
WARNING: This WILL interrupt call processing. You will be
|
WARNING: This WILL interrupt call processing. You will be
|
||||||
asked to confirm.
|
asked to confirm. The coredump will be written to /tmp if
|
||||||
|
$OUTPUTDIR is not defined.
|
||||||
|
|
||||||
--RUNNING
|
--RUNNING
|
||||||
Same as --running but without the confirmation prompt.
|
Same as --running but without the confirmation prompt.
|
||||||
@@ -69,10 +70,11 @@ DESCRIPTION
|
|||||||
/usr/sbin/asterisk, /usr/lib(64)/libasterisk* and
|
/usr/sbin/asterisk, /usr/lib(64)/libasterisk* and
|
||||||
/usr/lib(64)/asterisk as those files are needed to properly
|
/usr/lib(64)/asterisk as those files are needed to properly
|
||||||
examine the coredump. The file will be named
|
examine the coredump. The file will be named
|
||||||
/tmp/asterisk.<timestamp>.coredumps.tar.gz or
|
$OUTPUTDIR/asterisk.<timestamp>.coredumps.tar.gz or
|
||||||
/tmp/asterisk-<uniqueid>.coredumps.tar.gz if
|
$OUTPUTDIR/asterisk-<uniqueid>.coredumps.tar.gz if
|
||||||
--tarball-uniqueid was specified.
|
--tarball-uniqueid was specified.
|
||||||
WARNING: This file could 1gb in size!
|
WARNING: This file could 1gb in size!
|
||||||
|
Mutually exclusive with --tartball-results
|
||||||
|
|
||||||
--delete-coredumps-after
|
--delete-coredumps-after
|
||||||
Deletes all processed coredumps regardless of whether
|
Deletes all processed coredumps regardless of whether
|
||||||
@@ -81,7 +83,8 @@ DESCRIPTION
|
|||||||
--tarball-results
|
--tarball-results
|
||||||
Creates a gzipped tarball of all result files produced.
|
Creates a gzipped tarball of all result files produced.
|
||||||
The tarball name will be:
|
The tarball name will be:
|
||||||
/tmp/asterisk.<timestamp>.results.tar.gz
|
$OUTPUTDIR/asterisk.<timestamp>.results.tar.gz
|
||||||
|
Mutually exclusive with --tartball-coredumps
|
||||||
|
|
||||||
--delete-results-after
|
--delete-results-after
|
||||||
Deletes all processed results regardless of whether
|
Deletes all processed results regardless of whether
|
||||||
@@ -89,6 +92,10 @@ DESCRIPTION
|
|||||||
to use this option unless you have also specified
|
to use this option unless you have also specified
|
||||||
--tarball-results.
|
--tarball-results.
|
||||||
|
|
||||||
|
--tarball-config
|
||||||
|
Adds the contents of /etc/asterisk to the tarball created
|
||||||
|
with --tarball-coredumps or --tarball-results.
|
||||||
|
|
||||||
--tarball-uniqueid="<uniqueid>"
|
--tarball-uniqueid="<uniqueid>"
|
||||||
Normally DATEFORMAT is used to make the tarballs unique
|
Normally DATEFORMAT is used to make the tarballs unique
|
||||||
but you can use your own unique id in the tarball names
|
but you can use your own unique id in the tarball names
|
||||||
@@ -130,6 +137,10 @@ DESCRIPTION
|
|||||||
NOTES
|
NOTES
|
||||||
You must be root to use $prog.
|
You must be root to use $prog.
|
||||||
|
|
||||||
|
$OUTPUTDIR can be read from the current environment or from the
|
||||||
|
ast_debug_tools.conf file described below. If not specified,
|
||||||
|
work products are placed in the same directory as the core file.
|
||||||
|
|
||||||
The script relies on not only bash, but also recent GNU date and
|
The script relies on not only bash, but also recent GNU date and
|
||||||
gdb with python support. *BSD operating systems may require
|
gdb with python support. *BSD operating systems may require
|
||||||
installation of the 'coreutils' and 'devel/gdb' packagess and minor
|
installation of the 'coreutils' and 'devel/gdb' packagess and minor
|
||||||
@@ -166,6 +177,12 @@ FILES
|
|||||||
# anyway.
|
# anyway.
|
||||||
COREDUMPS=(/tmp/core[-._]asterisk!(*.txt) /tmp/core[-._]\$(hostname)!(*.txt))
|
COREDUMPS=(/tmp/core[-._]asterisk!(*.txt) /tmp/core[-._]\$(hostname)!(*.txt))
|
||||||
|
|
||||||
|
# The directory to contain output files and work directories.
|
||||||
|
# For output from existing core files, the default is the
|
||||||
|
# directory that the core file is found in. For core files
|
||||||
|
# produced from a running process, the default is /tmp.
|
||||||
|
OUTPUTDIR=/some/directory
|
||||||
|
|
||||||
# Date command for the "running" coredump and tarballs.
|
# Date command for the "running" coredump and tarballs.
|
||||||
# DATEFORMAT will be executed to get the timestamp.
|
# DATEFORMAT will be executed to get the timestamp.
|
||||||
# Don't put quotes around the format string or they'll be
|
# Don't put quotes around the format string or they'll be
|
||||||
@@ -227,6 +244,13 @@ if [ -z "$GDB" ] ; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ -n "$OUTPUTDIR" ] ; then
|
||||||
|
if [ ! -d "$OUTPUTDIR" ] ; then
|
||||||
|
echo "OUTPUTDIR $OUTPUTDIR doesn't exists or is not a directory"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
if [ ${#COREDUMPS[@]} -eq 0 ] ; then
|
if [ ${#COREDUMPS[@]} -eq 0 ] ; then
|
||||||
COREDUMPS+=(/tmp/core[-._]asterisk!(*.txt) /tmp/core[-._]$(hostname)!(*.txt))
|
COREDUMPS+=(/tmp/core[-._]asterisk!(*.txt) /tmp/core[-._]$(hostname)!(*.txt))
|
||||||
fi
|
fi
|
||||||
@@ -326,6 +350,10 @@ fi
|
|||||||
# Timestamp to use for output files
|
# Timestamp to use for output files
|
||||||
df=${tarball_uniqueid:-$(${DATEFORMAT})}
|
df=${tarball_uniqueid:-$(${DATEFORMAT})}
|
||||||
|
|
||||||
|
if [ -z "$asterisk_bin" ]; then
|
||||||
|
asterisk_bin=$(which asterisk)
|
||||||
|
fi
|
||||||
|
|
||||||
if $running || $RUNNING ; then
|
if $running || $RUNNING ; then
|
||||||
# We need to go through some gyrations to find the pid of the running
|
# We need to go through some gyrations to find the pid of the running
|
||||||
# MAIN asterisk process and not someone or something running asterisk -r.
|
# MAIN asterisk process and not someone or something running asterisk -r.
|
||||||
@@ -351,9 +379,9 @@ if $running || $RUNNING ; then
|
|||||||
read -p "WARNING: Taking a core dump of the running asterisk instance will suspend call processing while the dump is saved. Do you wish to continue? (y/N) " answer
|
read -p "WARNING: Taking a core dump of the running asterisk instance will suspend call processing while the dump is saved. Do you wish to continue? (y/N) " answer
|
||||||
fi
|
fi
|
||||||
if [[ "$answer" =~ ^[Yy] ]] ; then
|
if [[ "$answer" =~ ^[Yy] ]] ; then
|
||||||
cf="/tmp/core-asterisk-running-$df"
|
cf="${OUTPUTDIR:-/tmp}/core-asterisk-running-$df"
|
||||||
echo "Dumping running asterisk process to $cf"
|
echo "Dumping running asterisk process to $cf"
|
||||||
${GDB} -p $pid -q --batch --ex "gcore $cf" >/dev/null 2>&1
|
${GDB} ${asterisk_bin} -p $pid -q --batch --ex "gcore $cf" >/dev/null 2>&1
|
||||||
COREDUMPS+=("$cf")
|
COREDUMPS+=("$cf")
|
||||||
else
|
else
|
||||||
echo "Skipping dump of running process"
|
echo "Skipping dump of running process"
|
||||||
@@ -370,20 +398,22 @@ fi
|
|||||||
# and save them to /tmp/.gdbinit
|
# and save them to /tmp/.gdbinit
|
||||||
|
|
||||||
ss=`egrep -n "^#@@@SCRIPTSTART@@@" $0 |cut -f1 -d:`
|
ss=`egrep -n "^#@@@SCRIPTSTART@@@" $0 |cut -f1 -d:`
|
||||||
tail -n +${ss} $0 >/tmp/.ast_coredumper.gdbinit
|
tail -n +${ss} $0 >${OUTPUTDIR:-/tmp}/.ast_coredumper.gdbinit
|
||||||
|
|
||||||
# Now iterate over the coredumps and dump the debugging info
|
# Now iterate over the coredumps and dump the debugging info
|
||||||
for i in ${!COREDUMPS[@]} ; do
|
for i in ${!COREDUMPS[@]} ; do
|
||||||
cf=${COREDUMPS[$i]}
|
cf=${COREDUMPS[$i]}
|
||||||
echo "Processing $cf"
|
echo "Processing $cf"
|
||||||
if [ -z "$asterisk_bin" ]; then
|
|
||||||
asterisk_bin=$(which asterisk)
|
cfdir=`dirname ${cf}`
|
||||||
fi
|
cfname=`basename ${cf}`
|
||||||
${GDB} -n --batch -q --ex "source /tmp/.ast_coredumper.gdbinit" "$asterisk_bin" "$cf" 2>/dev/null | (
|
outputdir=${OUTPUTDIR:-${cfdir}}
|
||||||
|
|
||||||
|
${GDB} -n --batch -q --ex "source ${OUTPUTDIR:-/tmp}/.ast_coredumper.gdbinit" "$asterisk_bin" "$cf" 2>/dev/null | (
|
||||||
of=/dev/null
|
of=/dev/null
|
||||||
while IFS= read line ; do
|
while IFS= read line ; do
|
||||||
if [[ "$line" =~ !@!@!@!\ ([^\ ]+)\ !@!@!@! ]] ; then
|
if [[ "$line" =~ !@!@!@!\ ([^\ ]+)\ !@!@!@! ]] ; then
|
||||||
of=${cf}-${BASH_REMATCH[1]}
|
of=${outputdir}/${cfname}-${BASH_REMATCH[1]}
|
||||||
of=${of//:/-}
|
of=${of//:/-}
|
||||||
rm -f "$of"
|
rm -f "$of"
|
||||||
echo "Creating $of"
|
echo "Creating $of"
|
||||||
@@ -391,50 +421,58 @@ for i in ${!COREDUMPS[@]} ; do
|
|||||||
echo -e $"$line" >> "$of"
|
echo -e $"$line" >> "$of"
|
||||||
done
|
done
|
||||||
)
|
)
|
||||||
done
|
|
||||||
|
|
||||||
if $tarball_coredumps ; then
|
if $tarball_coredumps ; then
|
||||||
tf=/tmp/asterisk-$df.coredumps.tar.gz
|
cfname=${cfname//:/-}
|
||||||
echo "Creating $tf"
|
tf=${outputdir}/${cfname}.tar.gz
|
||||||
dest=/tmp/asterisk-$df
|
echo "Creating ${tf}"
|
||||||
rm -rf $dest 2>/dev/null || :
|
|
||||||
libdir=usr/lib
|
dest=${outputdir}/${cfname}.output
|
||||||
[ -d /usr/lib64 ] && libdir+=64
|
rm -rf ${dest} 2>/dev/null || :
|
||||||
mkdir -p $dest/tmp $dest/$libdir/asterisk $dest/etc $dest/usr/sbin
|
|
||||||
for i in ${!COREDUMPS[@]} ; do
|
libdir=usr/lib
|
||||||
ln -s "${COREDUMPS[@]}" $dest/"${COREDUMPS[@]}"
|
[ -d /usr/lib64 ] && libdir+=64
|
||||||
cp "${COREDUMPS[@]}"*.txt $dest/tmp/
|
mkdir -p ${dest}/tmp ${dest}/${libdir}/asterisk ${dest}/etc ${dest}/usr/sbin
|
||||||
done
|
|
||||||
cp /etc/os-release $dest/etc/
|
ln -s ${cf} ${dest}/tmp/${cfname}
|
||||||
cp -a /$libdir/libasterisk* $dest/$libdir/
|
cp ${outputdir}/${cfname}*.txt ${dest}/tmp/
|
||||||
cp -a /$libdir/asterisk/* $dest/$libdir/asterisk/
|
cp /etc/os-release ${dest}/etc/
|
||||||
cp -a /usr/sbin/asterisk $dest/usr/sbin
|
if $tarball_config ; then
|
||||||
rm -rf $tf
|
cp -a /etc/asterisk ${dest}/etc/
|
||||||
tar -chzf $tf --transform="s/^[.]/$df/" -C $dest .
|
fi
|
||||||
rm -rf $dest
|
cp -a /${libdir}/libasterisk* ${dest}/${libdir}/
|
||||||
echo "Created $tf"
|
cp -a /${libdir}/asterisk/* ${dest}/${libdir}/asterisk/
|
||||||
fi
|
cp -a /usr/sbin/asterisk ${dest}/usr/sbin
|
||||||
|
rm -rf ${tf}
|
||||||
|
tar -chzf ${tf} --transform="s/^[.]/${cfname}/" -C ${dest} .
|
||||||
|
rm -rf ${dest}
|
||||||
|
echo "Created $tf"
|
||||||
|
elif $tarball_results ; then
|
||||||
|
cfname=${cfname//:/-}
|
||||||
|
tf=${outputdir}/${cfname}.tar.gz
|
||||||
|
echo "Creating ${tf}"
|
||||||
|
|
||||||
|
dest=${outputdir}/${cfname}.output
|
||||||
|
rm -rf ${dest} 2>/dev/null || :
|
||||||
|
mkdir -p ${dest}
|
||||||
|
cp ${outputdir}/${cfname}*.txt ${dest}/
|
||||||
|
if $tarball_config ; then
|
||||||
|
mkdir -p ${dest}/etc
|
||||||
|
cp -a /etc/asterisk ${dest}/etc/
|
||||||
|
fi
|
||||||
|
tar -chzf ${tf} --transform="s/^[.]/${cfname}/" -C ${dest} .
|
||||||
|
rm -rf ${dest}
|
||||||
|
echo "Created $tf"
|
||||||
|
fi
|
||||||
|
|
||||||
if $delete_coredumps_after ; then
|
if $delete_coredumps_after ; then
|
||||||
for i in ${!COREDUMPS[@]} ; do
|
rm -rf "${cf}"
|
||||||
rm -rf "${COREDUMPS[$i]}"
|
fi
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
if $tarball_results ; then
|
if $delete_results_after ; then
|
||||||
tf=/tmp/asterisk-$df-results.tar
|
rm -rf "${cf//:/-}"-{brief,full,thread1,locks}.txt
|
||||||
echo "Creating $tf.gz"
|
fi
|
||||||
for i in ${!COREDUMPS[@]} ; do
|
done
|
||||||
tar -uvf $tf "${COREDUMPS[$i]//:/-}"-{brief,full,thread1,locks}.txt 2>/dev/null
|
|
||||||
done
|
|
||||||
gzip $tf
|
|
||||||
fi
|
|
||||||
|
|
||||||
if $delete_results_after ; then
|
|
||||||
for i in ${!COREDUMPS[@]} ; do
|
|
||||||
rm -rf "${COREDUMPS[$i]//:/-}"-{brief,full,thread1,locks}.txt
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
exit
|
exit
|
||||||
|
|
||||||
@@ -463,6 +501,9 @@ class DumpAsteriskCommand(gdb.Command):
|
|||||||
try:
|
try:
|
||||||
gdb.execute("p $_siginfo", from_tty)
|
gdb.execute("p $_siginfo", from_tty)
|
||||||
gdb.execute("info signal $_siginfo.si_signo")
|
gdb.execute("info signal $_siginfo.si_signo")
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
gdb.execute("thread apply 1 bt full", from_tty)
|
gdb.execute("thread apply 1 bt full", from_tty)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
@@ -470,6 +511,9 @@ class DumpAsteriskCommand(gdb.Command):
|
|||||||
try:
|
try:
|
||||||
gdb.execute("p $_siginfo", from_tty)
|
gdb.execute("p $_siginfo", from_tty)
|
||||||
gdb.execute("info signal $_siginfo.si_signo")
|
gdb.execute("info signal $_siginfo.si_signo")
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
gdb.execute("thread apply all bt", from_tty)
|
gdb.execute("thread apply all bt", from_tty)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
@@ -477,6 +521,9 @@ class DumpAsteriskCommand(gdb.Command):
|
|||||||
try:
|
try:
|
||||||
gdb.execute("p $_siginfo", from_tty)
|
gdb.execute("p $_siginfo", from_tty)
|
||||||
gdb.execute("info signal $_siginfo.si_signo")
|
gdb.execute("info signal $_siginfo.si_signo")
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
gdb.execute("thread apply all bt full", from_tty)
|
gdb.execute("thread apply all bt full", from_tty)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
@@ -484,6 +531,9 @@ class DumpAsteriskCommand(gdb.Command):
|
|||||||
try:
|
try:
|
||||||
gdb.execute("p $_siginfo", from_tty)
|
gdb.execute("p $_siginfo", from_tty)
|
||||||
gdb.execute("info signal $_siginfo.si_signo")
|
gdb.execute("info signal $_siginfo.si_signo")
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
gdb.execute("show_locks", from_tty)
|
gdb.execute("show_locks", from_tty)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
Reference in New Issue
Block a user