bash-syspose: Tracing a Shell Script by System Call
John Reiser
BitWagon Software LLC
September 2011
bash-syspose uses the LD_PRELOAD feature of GNU glibc C library, the PS4 feature of GNU bash shell, and a compatible two-line tweak to the source of bash itself, to trace a bash shell script by system call. An example output line on stderr is:
0.230123
check@6 < dracut-functions:646 16223:execve("/bin/uname",
["uname", "-m"], 60 vars) = 0
0.230123 |
elapsed time in seconds since start of tracing |
check@6 |
current executing function name and line number in script file |
dracut-functions:646 |
file name and line number of caller of current function |
16223 |
current process PID |
execve("/bin/uname", ... ) = 0 |
syscall(arguments) = result [similar to strace] |
bash-syspose is implemented as a small (500 lines) C-code shared library which intercepts (via LD_PRELOAD) selected system calls that bash makes. During interception, bash-syspose evaluates the PS4 prompt and uses the result as the main part of tracing output. A two-line tweak to the bash source makes evaluating PS4 essentially transparent to the rest of bash.
Usage:
0) Build the bash-syspose.so shared library:
cd bash-syspose-0.8
make
1) Modify the source code of bash-4.2 using the patch, then re-build bash.
2) Insert into the shell script:
unset LD_PRELOAD
PS4=' ${FUNCNAME[0]}@$LINENO < ${BASH_SOURCE[1]##*/}:${BASH_LINENO[0]}'
3) Invoke the shell script:
LD_PRELOAD=/path/to/bash-syspose.so /path/to/bash script-file-name args...
Notes:
bash-syspose is invoked via LD_PRELOAD, so for maximum safety the script should
unset LD_PRELOAD
to prevent the glibc runtime loader from pre-loading bash-syspose into all child execve(). The bash subroutine which evaluates PS4 has a distinctive name, and bash-syspose uses it as a weak external. This provides some protection if LD_PRELOAD of bash-syspose persists into a non-bash execve().
By default, bash limits the length of the expanded PS4 to char[100].
Code (including patch to bash):
http://BitWagon.com/bash-syspose/bash-syspose-0.8.tgz (5kB)