]>
Commit | Line | Data |
---|---|---|
e1e6f073 | 1 | #!/usr/bin/env bash |
627bf7c1 | 2 | |
1d506c26 | 3 | # Copyright (C) 2003-2024 Free Software Foundation, Inc. |
627bf7c1 EZ |
4 | |
5 | # This program is free software; you can redistribute it and/or modify | |
6 | # it under the terms of the GNU General Public License as published by | |
50efebf8 | 7 | # the Free Software Foundation; either version 3 of the License, or |
627bf7c1 | 8 | # (at your option) any later version. |
50efebf8 | 9 | # |
627bf7c1 EZ |
10 | # This program is distributed in the hope that it will be useful, |
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | # GNU General Public License for more details. | |
50efebf8 | 14 | # |
627bf7c1 | 15 | # You should have received a copy of the GNU General Public License |
50efebf8 | 16 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
627bf7c1 | 17 | |
627bf7c1 | 18 | # |
627bf7c1 EZ |
19 | # Script to generate a core file of a running program. |
20 | # It starts up gdb, attaches to the given PID and invokes the gcore command. | |
21 | # | |
22 | ||
627bf7c1 | 23 | # Need to check for -o option, but set default basename to "core". |
129eb0f1 | 24 | prefix=core |
627bf7c1 | 25 | |
cd93789b SL |
26 | # When the -a option is present, this may hold additional commands |
27 | # to ensure gdb dumps all mappings (OS dependent). | |
28 | dump_all_cmds=() | |
29 | ||
7e42bbed AH |
30 | data_directory_opt=() |
31 | ||
32 | while getopts :ao:d: opt; do | |
e1e6f073 | 33 | case "$opt" in |
cd93789b | 34 | a) |
e1e6f073 | 35 | case "$OSTYPE" in |
cd93789b SL |
36 | linux*) |
37 | dump_all_cmds=("-ex" "set use-coredump-filter off") | |
38 | dump_all_cmds+=("-ex" "set dump-excluded-mappings on") | |
39 | ;; | |
40 | esac | |
41 | ;; | |
42 | o) | |
129eb0f1 | 43 | prefix=$OPTARG |
cd93789b | 44 | ;; |
7e42bbed AH |
45 | d) |
46 | data_directory_opt=("--data-directory" "$OPTARG") | |
47 | ;; | |
cd93789b | 48 | *) |
7e42bbed | 49 | echo "usage: @GCORE_TRANSFORM_NAME@ [-a] [-o prefix] [-d data-directory] pid1 [pid2...pidN]" |
cd93789b SL |
50 | exit 2 |
51 | ;; | |
52 | esac | |
53 | done | |
54 | ||
55 | shift $((OPTIND-1)) | |
56 | ||
57 | if [ "$#" -eq "0" ] | |
627bf7c1 | 58 | then |
7e42bbed | 59 | echo "usage: @GCORE_TRANSFORM_NAME@ [-a] [-o prefix] [-d data-directory] pid1 [pid2...pidN]" |
cd93789b | 60 | exit 2 |
627bf7c1 EZ |
61 | fi |
62 | ||
87326c87 LM |
63 | # Attempt to fetch the absolute path to the gcore script that was |
64 | # called. | |
65 | binary_path=`dirname "$0"` | |
66 | ||
67 | if test "x$binary_path" = x. ; then | |
68 | # We got "." back as a path. This means the user executed | |
69 | # the gcore script locally (i.e. ./gcore) or called the | |
70 | # script via a shell interpreter (i.e. sh gcore). | |
71 | binary_basename=`basename "$0"` | |
72 | ||
73 | # If the gcore script was called like "sh gcore" and the script | |
74 | # lives in the current directory, "which" will not give us "gcore". | |
75 | # So first we check if the script is in the current directory | |
76 | # before using the output of "which". | |
77 | if test -f "$binary_basename" ; then | |
78 | # We have a local gcore script in ".". This covers the case of | |
79 | # doing "./gcore" or "sh gcore". | |
80 | binary_path="." | |
81 | else | |
82 | # The gcore script was not found in ".", which means the script | |
83 | # was called from somewhere else in $PATH by "sh gcore". | |
84 | # Extract the correct path now. | |
85 | binary_path_from_env=`which "$0"` | |
86 | binary_path=`dirname "$binary_path_from_env"` | |
87 | fi | |
88 | fi | |
89 | ||
90 | # Check if the GDB binary is in the expected path. If not, just | |
91 | # quit with a message. | |
e1e6f073 | 92 | if [ ! -f "$binary_path/@GDB_TRANSFORM_NAME@" ]; then |
87326c87 LM |
93 | echo "gcore: GDB binary (${binary_path}/@GDB_TRANSFORM_NAME@) not found" |
94 | exit 1 | |
95 | fi | |
96 | ||
627bf7c1 EZ |
97 | # Initialise return code. |
98 | rc=0 | |
99 | ||
100 | # Loop through pids | |
e1e6f073 | 101 | for pid in "$@" |
627bf7c1 | 102 | do |
3a674486 JK |
103 | # `</dev/null' to avoid touching interactive terminal if it is |
104 | # available but not accessible as GDB would get stopped on SIGTTIN. | |
8a6a8513 | 105 | "$binary_path/@GDB_TRANSFORM_NAME@" </dev/null \ |
7e42bbed | 106 | "${data_directory_opt[@]}" \ |
b91f93a0 | 107 | --nx --batch --readnever -iex 'set debuginfod enabled off' \ |
3a674486 | 108 | -ex "set pagination off" -ex "set height 0" -ex "set width 0" \ |
cd93789b | 109 | "${dump_all_cmds[@]}" \ |
129eb0f1 | 110 | -ex "attach $pid" -ex "gcore $prefix.$pid" -ex detach -ex quit |
dfb893af | 111 | |
129eb0f1 | 112 | if [ -r "$prefix.$pid" ] ; then |
627bf7c1 EZ |
113 | rc=0 |
114 | else | |
129eb0f1 | 115 | echo "@GCORE_TRANSFORM_NAME@: failed to create $prefix.$pid" |
627bf7c1 EZ |
116 | rc=1 |
117 | break | |
118 | fi | |
119 | ||
120 | ||
121 | done | |
122 | ||
123 | exit $rc |