OILS / demo / compare-strace.sh View on Github | oilshell.org

226 lines, 108 significant
1#!/usr/bin/env bash
2#
3# See what system calls shells make for various constructs. Similar to
4# test/syscall.sh.
5#
6# Usage:
7# demo/compare-strace.sh <function name>
8
9set -o nounset
10set -o pipefail
11set -o errexit
12
13readonly BASE_DIR=_tmp/survey-strace
14
15OSH=${OSH:-bin/osh}
16
17banner() {
18 echo
19 echo
20 echo -e -n "\t"; echo "$@"
21 echo
22 echo
23}
24
25redir-strace() {
26 ### trace relevant calls
27
28 strace -e open,fcntl,dup2,close -- "$@"
29}
30
31redir() {
32 #for sh in dash bash mksh bin/osh; do
33
34 # hm bin/osh and zsh have too many close() calls. I think this is the Python
35 # interpreter
36 for sh in dash bash mksh; do
37
38 banner "$sh"
39
40 #local code='exec 3>_tmp/3.txt; echo hello >&3; exec 3>&-; cat _tmp/3.txt'
41
42 #local code='exec 4>_tmp/4.txt; echo hello >&4; exec 4>&-; cat _tmp/4.txt'
43 #local code='true 2>&1'
44
45 local code='true > _tmp/out.txt'
46 redir-strace $sh -c "$code"
47 done
48}
49
50here-strace() {
51 local sh=$1
52 local dir
53 dir=$BASE_DIR/$(basename $sh)
54 # Not shifting
55
56 mkdir -v -p $dir
57
58 # -ff because it's a pipeline
59 strace -ff -o $dir/here -e 'open,close,fcntl,read,write,fork,execve' -- "$@"
60}
61
62here() {
63 mkdir -v -p $BASE_DIR
64
65 if false; then
66 # osh-cpp doesn't have $(dirname) in wrapper script
67 OSH=_bin/cxx-dbg/osh
68 ninja $OSH
69 fi
70
71 for sh in dash bash mksh $OSH; do
72
73 banner "$sh"
74
75 #local code='exec 3>_tmp/3.txt; echo hello >&3; exec 3>&-; cat _tmp/3.txt'
76
77 #local code='exec 4>_tmp/4.txt; echo hello >&4; exec 4>&-; cat _tmp/4.txt'
78 #local code='true 2>&1'
79
80 cat > $BASE_DIR/here.sh <<SHELL
81tac <<EOF
82one
83two
84three
85EOF
86SHELL
87
88 here-strace $sh $BASE_DIR/here.sh
89 done
90
91 if command -v tree; then
92 tree $BASE_DIR
93 fi
94}
95
96io-strace() {
97 ### trace relevant calls
98
99 # -ff because it's a pipeline
100 strace -ff -e 'open,close,fcntl,read,write' -- "$@"
101}
102
103readonly OSH_NATIVE=_bin/cxx-dbg/osh
104
105readonly READ_SH='
106{ echo "0123456789"; echo "ABCDEFGHIJ"; } |
107while read -r line; do echo $line; done
108'
109
110read-builtin() {
111 # RESULTS
112 #
113 # All shells read 1 byte at a time
114
115 for sh in dash bash $OSH_NATIVE; do
116 banner "$sh"
117
118 io-strace $sh -c "$READ_SH"
119 done
120}
121
122read-lines-from-disk-file() {
123 # dash can't read this script
124
125 # RESULTS:
126 # mksh: reads 512 bytes at a time
127 # bash: 80 and then 2620?
128 # osh_native: using libc readline, it's 832 bytes at a time.
129
130 # I think we can have a "regular file reader", which is different than a pipe
131 # reader?
132
133 for sh in mksh bash $OSH_NATIVE; do
134 banner "$sh"
135
136 # Run without args
137 io-strace $sh $0
138 done
139}
140
141read-lines-from-pipe() {
142 # RESULTS:
143 # - dash does read(8192), hm
144 # - mksh reads 1 byte at a time
145 # - bash reads 1 byte at a time
146 # - zsh reads 1 byte at a time
147 # - osh_native with libc does 832 bytes at time.
148
149 for sh in dash mksh bash zsh $OSH_NATIVE; do
150 banner "$sh"
151
152 # Run without args
153 io-strace sh -c "cat testdata/osh-runtime/hello_world.sh | $sh"
154 done
155}
156
157job-control-trace() {
158 ### trace relevant calls
159
160 # why isn't tcsetpgrp valid?
161 strace -ff -e fork,execve,setpgid -- "$@"
162}
163
164job-control() {
165 #for sh in dash bash mksh bin/osh; do
166
167 # hm bin/osh and zsh have too many close() calls. I think this is the Python
168 # interpreter
169 for sh in dash bash mksh zsh; do
170
171 echo
172 echo "--- $sh ---"
173 echo
174
175 local code='ls | wc -l'
176 job-control-trace $sh -i -c "$code"
177 done
178}
179
180interactive() {
181 local sh=dash
182 local code='ls | wc -l'
183
184 # is tcsetpgrp() an ioctl? It takes a file descriptor. I see setpgid() but
185 # not tcsetpgrp().
186
187 strace -c $sh -c "$code"
188 echo -----
189 strace -c $sh -i -c "$code"
190}
191
192#
193# Translation tests
194#
195
196_compare-native() {
197 local code=$1
198
199 rm -r -f -v $BASE_DIR
200 mkdir -p $BASE_DIR
201
202 ninja $OSH_NATIVE
203
204 strace -ff -o $BASE_DIR/py -- bin/osh -c "$code"
205 strace -ff -o $BASE_DIR/cpp -- $OSH_NATIVE -c "$code"
206
207 wc -l $BASE_DIR/*
208}
209
210native-command-sub() {
211 _compare-native 'echo $(echo hi)'
212}
213
214native-redirect() {
215 _compare-native 'echo hi > _tmp/redir'
216}
217
218native-read-builtin() {
219 _compare-native "$READ_SH"
220}
221
222if test $# -eq 0; then
223 echo "$0: expected arguments"
224else
225 "$@"
226fi