Issue
How can I bundle a core file with its associated executables and shared libraries?
When a program crashes, it generates a core file, that I can use to debug it with gdb. But if someone comes along behind me and "helpfully" recompiles the program with extra debugging turned on, or upgrades a package, or in any way messes with the system, that core file becomes useless.
So what I'd like is a way to bundle the core dump file with all of the other binaries that it references, into one big file.
Then, of course, I also need a way to open this file in gdb. I don't want to have to "extract" the files back to their original location and overwrite upgraded or changed binaries. I'm imagining a shell script that extracts the binaries to a temp directory and then tells gdb to look there.
Solution
gdb already has the information that you wanted (info sharedlib
):
$ gdb -ex 'set height 0' -ex 'set confirm off' \
-ex 'file /path/to/exe' -ex 'core-file core.pid' \
-ex 'info sharedlib' -ex quit
So naturally you can ask gdb to give you this list, and from there you can create a "gdb-bundle" tarball that contains the executable and all the shared libraries that gdb reported.
I wrote a script to automate this:
#!/bin/sh
me=$(basename $0)
usage() {
echo "Usage:
$me -p <pid>
$me <executable> <core>
DESCRIPTION
$me - Creates a tarball containing the executable, it's core dump and
all the shared libraries that gdb said it loads.
OPTIONS
-p <pid> A running process id of a process to be bundled.
-h Show this help message"
}
pid=
while getopts hp: opt
do
case "$opt" in
p)
pid="$OPTARG"
;;
h)
usage
exit
;;
\?)
echo Unknown option
exit
;;
esac
done
shift $(($OPTIND -1))
executable=$1
corename=$2
if [ -n "$pid" ]; then
test "$pid" -gt 0 || { echo "pid must be numeric"; exit 1; }
proc=/proc/$pid/exe
executable=`readlink -e $proc` ||
{ echo "Could not readlink $proc"; exit 1; }
corename=${basename}.$pid.core
else
test -z "$executable" && usage && exit 1;
test -z "$corename" && usage && exit 1;
fi
basename=$(basename $executable)
if [ -n "$pid" ]; then
sharedlibs=$(gdb -ex "attach $pid" -ex 'set height 0' \
-ex 'set confirm off' -ex "generate-core-file $corename" \
-ex 'info sharedlib' -ex quit|
sed -n '/Shared Object Library/,/^(/p'|grep -E '(Yes|No)'|
sed -e 's,[^/]\+,,') || exit 1
dir="gdb-${basename}.$pid.$(date +%F-%H%M%S)"
else
sharedlibs=$(gdb -ex 'set height 0' -ex 'set confirm off' \
-ex "file $executable" -ex "core-file $corename" \
-ex 'info sharedlib' -ex quit|
sed -n '/Shared Object Library/,/^(/p'|grep -E '(Yes|No)'|
sed -e 's,[^/]\+,,') || exit 1
dir="gdb-${basename}.$(date +%F-%H%M%S)"
fi
mkdir "$dir" && cp "$corename" "$dir" &&
tar chf - $sharedlibs $executable|tar -C $dir -xf - &&
echo -e "gdb:\n\tgdb -ex 'set solib-absolute-prefix ./'" \
"-ex 'file .$executable' -ex 'core-file ./$corename' " \
> $dir/makefile &&
echo tar czf $dir.tar.gz $dir &&
tar czf $dir.tar.gz $dir
Answered By - holygeek Answer Checked By - Mildred Charles (WPSolving Admin)