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)