#!/usr/bin/sh
##
## Dump a process information
## Copyright (c) 2007-2008 SATOH Fumiyasu @ OSSTech Corp., Japan
##                         <https://www.OSSTech.co.jp/>
##
## License: GNU General Public License version 2 or later
## Date: 2008-04-18, since 2007-03-31
##

set -u
umask 0077

LC_ALL="C"
PATH="/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin"
export LC_ALL PATH

if [ -d /dev/shm ]; then
  tmp_dir="/dev/shm/pinfo.$$.tmp"
else
  tmp_dir="/var/tmp/pinfo.$$.tmp"
fi

cmd_usage="Usage: $0 PID [LOGFILE]"

if [ $# -lt 1 ]; then
  echo "$cmd_usage"
  exit 0
fi

target_pid="$1"; shift
log_basename="${1:--}"

if [ x"$log_basename" != x"-" ]; then
  log_file="$log_basename.$(date '+%Y%m%d%H%M%S').$$.log"
else
  log_file="/dev/stdout"
fi

log_dir="$(dirname "$log_basename")"
if [ ! -d "$log_dir" ] || [ ! -w "$log_dir" ]; then
  echo "$0: error: log directory is not writable: $log_dir" 1>&2
  exit 1
fi

mkdir "$tmp_dir" || exit 1
trap 'rm -rf -- "$tmp_dir"' 0
trap 'exit 1' HUP INT QUIT TERM PIPE

pinfo_gdb()
{
  type gdb >/dev/null 2>&1 || return

  if [ -f "/proc/$target_pid/exe" ]; then
    target_cmd="/proc/$target_pid/exe"
  elif [ -f "/proc/$target_pid/object/a.out" ]; then
    target_cmd="/proc/$target_pid/object/a.out"
  else
    return
  fi

  gdb_cmd_file="$tmp_dir/gdb-cmd"
  cat <<EOF_GDB_CMD  >"$gdb_cmd_file"
set height 0
up 8
bt full
quit
EOF_GDB_CMD

  gdb -batch -n -x "$gdb_cmd_file" "$target_cmd" "$target_pid" \
  |sed 's#^#gdb: #'
}

pinfo_lsof()
{
  type lsof >/dev/null 2>&1 || return

  lsof -n -p "$target_pid" |sed 's#^#lsof: #'
}

pinfo_pcmd()
{
  for pcmd in ptree pstack pflags pcred psig pfiles pwdx pmap; do
    type "$pcmd" >/dev/null 2>&1 || continue
    "$pcmd" "$target_pid" |sed "s#^#$pcmd: #"
  done
}

touch "$log_file"
{
  pinfo_gdb
  pinfo_lsof
  pinfo_pcmd
} >>"$log_file" 2>&1
