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

178 lines, 85 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
13banner() {
14 echo
15 echo
16 echo -e -n "\t"; echo "$@"
17 echo
18 echo
19}
20
21redir-strace() {
22 ### trace relevant calls
23
24 strace -e open,fcntl,dup2,close -- "$@"
25}
26
27redir() {
28 #for sh in dash bash mksh bin/osh; do
29
30 # hm bin/osh and zsh have too many close() calls. I think this is the Python
31 # interpreter
32 for sh in dash bash mksh; do
33
34 banner "$sh"
35
36 #local code='exec 3>_tmp/3.txt; echo hello >&3; exec 3>&-; cat _tmp/3.txt'
37
38 #local code='exec 4>_tmp/4.txt; echo hello >&4; exec 4>&-; cat _tmp/4.txt'
39 #local code='true 2>&1'
40
41 local code='true > _tmp/out.txt'
42 redir-strace $sh -c "$code"
43 done
44}
45
46io-strace() {
47 ### trace relevant calls
48
49 # -ff because it's a pipeline
50 strace -ff -e 'open,close,fcntl,read,write' -- "$@"
51}
52
53readonly OSH_NATIVE=_bin/cxx-dbg/osh
54
55readonly READ_SH='
56{ echo "0123456789"; echo "ABCDEFGHIJ"; } |
57while read -r line; do echo $line; done
58'
59
60read-builtin() {
61 # RESULTS
62 #
63 # All shells read 1 byte at a time
64
65 for sh in dash bash $OSH_NATIVE; do
66 banner "$sh"
67
68 io-strace $sh -c "$READ_SH"
69 done
70}
71
72read-lines-from-disk-file() {
73 # dash can't read this script
74
75 # RESULTS:
76 # mksh: reads 512 bytes at a time
77 # bash: 80 and then 2620?
78 # osh_native: using libc readline, it's 832 bytes at a time.
79
80 # I think we can have a "regular file reader", which is different than a pipe
81 # reader?
82
83 for sh in mksh bash $OSH_NATIVE; do
84 banner "$sh"
85
86 # Run without args
87 io-strace $sh $0
88 done
89}
90
91read-lines-from-pipe() {
92 # RESULTS:
93 # - dash does read(8192), hm
94 # - mksh reads 1 byte at a time
95 # - bash reads 1 byte at a time
96 # - zsh reads 1 byte at a time
97 # - osh_native with libc does 832 bytes at time.
98
99 for sh in dash mksh bash zsh $OSH_NATIVE; do
100 banner "$sh"
101
102 # Run without args
103 io-strace sh -c "cat testdata/osh-runtime/hello_world.sh | $sh"
104 done
105}
106
107job-control-trace() {
108 ### trace relevant calls
109
110 # why isn't tcsetpgrp valid?
111 strace -ff -e fork,execve,setpgid -- "$@"
112}
113
114job-control() {
115 #for sh in dash bash mksh bin/osh; do
116
117 # hm bin/osh and zsh have too many close() calls. I think this is the Python
118 # interpreter
119 for sh in dash bash mksh zsh; do
120
121 echo
122 echo "--- $sh ---"
123 echo
124
125 local code='ls | wc -l'
126 job-control-trace $sh -i -c "$code"
127 done
128}
129
130interactive() {
131 local sh=dash
132 local code='ls | wc -l'
133
134 # is tcsetpgrp() an ioctl? It takes a file descriptor. I see setpgid() but
135 # not tcsetpgrp().
136
137 strace -c $sh -c "$code"
138 echo -----
139 strace -c $sh -i -c "$code"
140}
141
142#
143# Translation tests
144#
145
146readonly BASE_DIR=_tmp/strace
147
148_compare-native() {
149 local code=$1
150
151 rm -r -f -v $BASE_DIR
152 mkdir -p $BASE_DIR
153
154 ninja $OSH_NATIVE
155
156 strace -ff -o $BASE_DIR/py -- bin/osh -c "$code"
157 strace -ff -o $BASE_DIR/cpp -- $OSH_NATIVE -c "$code"
158
159 wc -l $BASE_DIR/*
160}
161
162native-command-sub() {
163 _compare-native 'echo $(echo hi)'
164}
165
166native-redirect() {
167 _compare-native 'echo hi > _tmp/redir'
168}
169
170native-read-builtin() {
171 _compare-native "$READ_SH"
172}
173
174if test $# -eq 0; then
175 echo "$0: expected arguments"
176else
177 "$@"
178fi