Last active
July 21, 2022 01:43
-
-
Save tripleee/0aea6984632c30956329 to your computer and use it in GitHub Desktop.
make a shell command show a call trace on failure
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
:<<'=cut' | |
=head1 NAME | |
traceback - make a shell command show a call trace on failure | |
=head1 SYNOPSIS | |
ln -s /path/to/traceback bin/problematiccommand | |
=head1 DESCRIPTION | |
B<traceback> is an aid | |
for debugging an error message from a shell script which is | |
too uninformative and/or comes from an unknown source. | |
As long as you know which individual command has an error, | |
and as long as it properly sets the errorlevel on error, | |
you can obtain a traceback when the error happens to see | |
what was going on in the calling script's little mind. | |
=head1 USAGE EXAMPLES | |
sh$ mkdir $HOME/bin/traceback | |
sh$ PATH=$HOME/bin/traceback:$PATH | |
sh$ ln -s /path/to/traceback $HOME/bin/traceback/sed | |
sh$ hash -r sed | |
sh$ type sed | |
sed is hashed (/home/you/bin/traceback/sed) | |
sh$ sed 's%foo/bar/' | |
/bin/sed: -e expression #1, char 9: unterminated `s' command | |
traceback for process 1163: | |
* 1163 /bin/sh /home/you/bin/traceback/sed s%foo/bar/ (cwd: /tmp) | |
* 4245 /bin/bash (cwd: /home/you/project) | |
* 4239 SCREEN -e ^Ll (cwd: denied) | |
... or, perhaps more realistically | |
bash$ cd problematicproject | |
bash$ ./problematicscript | |
/usr/bin/expr: non-numeric argument | |
./problematicscript: catastrophic failure, aborting at line 93845 | |
bash$ !? fsck | |
!?: event not found | |
bash$ mkdir bin | |
bash$ ln -s /usr/local/bin/traceback bin/expr | |
bash$ PATH=`pwd`/bin:$PATH ./problematicscript | |
/usr/bin/expr: non-numeric argument | |
traceback for process 3908: | |
3908 /bin/sh /home/you/work/problematicproject/bin/expr 1 + var (cwd: ...) | |
3905 /bin/sh /home/you/bin/calculatestuff /tmp/subscript.7Fg49Ab (cwd: ...) | |
3901 /bin/sh subscript fortytwo (cwd: /home/you/work/problematicproject) | |
3887 /bin/sh problematicscript | |
1122 -bash (cwd: /home/you/work/problematicproject) | |
./problematicscript: catastrophic failure, aborting at line 93845 | |
=head1 PORTABILITY | |
This relies on specific L<ps(1)> options, | |
so is not portable. | |
Currently, this is Linux only | |
(or possibly even Debian only). | |
Also, requires L<lsof(1)>. | |
=head1 AUTHOR | |
tripleee | |
L<tripleee@users.noreply.github.com> | |
=head1 LICENSE | |
There is no explicit license at this point in time. | |
If it bothers you, get in touch and I'll add the necessary | |
copyright notices etc. | |
My intent is to distribute this under the | |
BSD license (without advertising clause, of course). | |
=head1 SEE ALSO | |
L<sh(1)>, | |
L<python(1)>; | |
L<ps(1)>, | |
L<lsof(1)> | |
=cut | |
cmd=$(basename "$0") | |
pth=$(type -a -p "$cmd" | fgrep -vx "$0" | head -n 1) | |
"$pth" "$@" | |
rc=$? | |
case $rc in | |
0) exit 0;; | |
esac | |
# ps options for Linux: | |
# -o field1= -o field2= ... -- output these fields, with no header line | |
# -p -- (needs to be last) show process with pid ... | |
psopts='-o ppid= -o pid= -o args= -p' | |
# terminating condition: stop looping when comm= matches one of these | |
toplvl='-bash | SCREEN | init' | |
p=$$ | |
echo "traceback for process $p:" >&2 | |
while true; do | |
set -- `ps $psopts $p` | |
p=$1 | |
shift | |
######## FIXME: horrid | |
cwd=$(set -- $(lsof -d cwd -a -p $1 | tail -n 1); echo "$9") | |
echo '*' "$@" "(cwd: $cwd)" >&2 | |
#lsof -p $1 | sed 's/^/** /' | |
case $1 in 0|1) break;; esac | |
eval case \$2 in $toplvl\) break\;\; esac | |
done | |
exit $rc |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment