-#!/bin/sh
+#!/usr/bin/env bash
-# Copyright (C) 2003-2013 Free Software Foundation, Inc.
+# Copyright (C) 2003-2020 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# It starts up gdb, attaches to the given PID and invokes the gcore command.
#
+# Need to check for -o option, but set default basename to "core".
+prefix=core
+
+# When the -a option is present, this may hold additional commands
+# to ensure gdb dumps all mappings (OS dependent).
+dump_all_cmds=()
+
+while getopts :ao: opt; do
+ case "$opt" in
+ a)
+ case "$OSTYPE" in
+ linux*)
+ dump_all_cmds=("-ex" "set use-coredump-filter off")
+ dump_all_cmds+=("-ex" "set dump-excluded-mappings on")
+ ;;
+ esac
+ ;;
+ o)
+ prefix=$OPTARG
+ ;;
+ *)
+ echo "usage: @GCORE_TRANSFORM_NAME@ [-a] [-o prefix] pid1 [pid2...pidN]"
+ exit 2
+ ;;
+ esac
+done
+
+shift $((OPTIND-1))
+
if [ "$#" -eq "0" ]
then
- echo "usage: @GCORE_TRANSFORM_NAME@ [-o filename] pid"
+ echo "usage: @GCORE_TRANSFORM_NAME@ [-a] [-o prefix] pid1 [pid2...pidN]"
exit 2
fi
-# Need to check for -o option, but set default basename to "core".
-name=core
+# Attempt to fetch the absolute path to the gcore script that was
+# called.
+binary_path=`dirname "$0"`
-if [ "$1" = "-o" ]
-then
- if [ "$#" -lt "3" ]
- then
- # Not enough arguments.
- echo "usage: @GCORE_TRANSFORM_NAME@ [-o filename] pid"
- exit 2
- fi
- name=$2
-
- # Shift over to start of pid list
- shift; shift
+if test "x$binary_path" = x. ; then
+ # We got "." back as a path. This means the user executed
+ # the gcore script locally (i.e. ./gcore) or called the
+ # script via a shell interpreter (i.e. sh gcore).
+ binary_basename=`basename "$0"`
+
+ # If the gcore script was called like "sh gcore" and the script
+ # lives in the current directory, "which" will not give us "gcore".
+ # So first we check if the script is in the current directory
+ # before using the output of "which".
+ if test -f "$binary_basename" ; then
+ # We have a local gcore script in ".". This covers the case of
+ # doing "./gcore" or "sh gcore".
+ binary_path="."
+ else
+ # The gcore script was not found in ".", which means the script
+ # was called from somewhere else in $PATH by "sh gcore".
+ # Extract the correct path now.
+ binary_path_from_env=`which "$0"`
+ binary_path=`dirname "$binary_path_from_env"`
+ fi
+fi
+
+# Check if the GDB binary is in the expected path. If not, just
+# quit with a message.
+if [ ! -f "$binary_path/@GDB_TRANSFORM_NAME@" ]; then
+ echo "gcore: GDB binary (${binary_path}/@GDB_TRANSFORM_NAME@) not found"
+ exit 1
fi
# Initialise return code.
rc=0
# Loop through pids
-for pid in $*
+for pid in "$@"
do
# `</dev/null' to avoid touching interactive terminal if it is
# available but not accessible as GDB would get stopped on SIGTTIN.
- @GDB_TRANSFORM_NAME@ </dev/null --nx --batch \
+ "$binary_path/@GDB_TRANSFORM_NAME@" </dev/null \
+ --nx --batch --readnever \
-ex "set pagination off" -ex "set height 0" -ex "set width 0" \
- -ex "attach $pid" -ex "gcore $name.$pid" -ex detach -ex quit
+ "${dump_all_cmds[@]}" \
+ -ex "attach $pid" -ex "gcore $prefix.$pid" -ex detach -ex quit
- if [ -r $name.$pid ] ; then
+ if [ -r "$prefix.$pid" ] ; then
rc=0
else
- echo "@GCORE_TRANSFORM_NAME@: failed to create $name.$pid"
+ echo "@GCORE_TRANSFORM_NAME@: failed to create $prefix.$pid"
rc=1
break
fi