深くダイビングしたいLinuxいつでも使える優れたツールstrace
(バージョン: 4.11)存在するUbuntu 16.04 LTS以下のように名前がついた理由が気になります。
# strace -c w
単純なシステムコール以上のものが必要です。Python文字列を10回印刷するスクリプト?
より具体的に言えば、出力は次のようになります。strace -c w
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
shan tty7 :0 13:20 3:37m 8:14 0.72s /sbin/upstart --user
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
61.67 0.000037 0 487 4 open
23.33 0.000014 0 478 read
15.00 0.000009 0 485 close
0.00 0.000000 0 3 write
0.00 0.000000 0 226 stat
0.00 0.000000 0 38 fstat
0.00 0.000000 0 27 lseek
0.00 0.000000 0 63 mmap
0.00 0.000000 0 31 mprotect
0.00 0.000000 0 14 munmap
0.00 0.000000 0 5 brk
0.00 0.000000 0 22 rt_sigaction
0.00 0.000000 0 1 rt_sigprocmask
0.00 0.000000 0 1 ioctl
0.00 0.000000 0 19 19 access
0.00 0.000000 0 30 alarm
0.00 0.000000 0 2 socket
0.00 0.000000 0 2 2 connect
0.00 0.000000 0 1 execve
0.00 0.000000 0 1 uname
0.00 0.000000 0 20 fcntl
0.00 0.000000 0 2 getdents
0.00 0.000000 0 1 getrlimit
0.00 0.000000 0 2 2 statfs
0.00 0.000000 0 1 arch_prctl
0.00 0.000000 0 1 futex
0.00 0.000000 0 1 set_tid_address
0.00 0.000000 0 1 set_robust_list
------ ----------- ----------- --------- --------- ----------------
100.00 0.000060 1965 27 total
~のためstrace -c /tmp/loop.py
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
100.00 0.000160 9 18 getdents
0.00 0.000000 0 54 read
0.00 0.000000 0 10 write
0.00 0.000000 0 44 2 open
0.00 0.000000 0 45 close
0.00 0.000000 0 108 16 stat
0.00 0.000000 0 69 fstat
0.00 0.000000 0 10 lstat
0.00 0.000000 0 30 6 lseek
0.00 0.000000 0 32 mmap
0.00 0.000000 0 16 mprotect
0.00 0.000000 0 1 munmap
0.00 0.000000 0 14 brk
0.00 0.000000 0 68 rt_sigaction
0.00 0.000000 0 1 rt_sigprocmask
0.00 0.000000 0 13 1 ioctl
0.00 0.000000 0 9 9 access
0.00 0.000000 0 10 select
0.00 0.000000 0 3 dup
0.00 0.000000 0 1 execve
0.00 0.000000 0 1 fcntl
0.00 0.000000 0 4 2 readlink
0.00 0.000000 0 1 getrlimit
0.00 0.000000 0 1 sysinfo
0.00 0.000000 0 1 getuid
0.00 0.000000 0 1 getgid
0.00 0.000000 0 1 geteuid
0.00 0.000000 0 1 getegid
0.00 0.000000 0 1 sigaltstack
0.00 0.000000 0 1 arch_prctl
0.00 0.000000 0 1 futex
0.00 0.000000 0 1 set_tid_address
0.00 0.000000 0 1 set_robust_list
0.00 0.000000 0 1 getrandom
------ ----------- ----------- --------- --------- ----------------
100.00 0.000160 573 36 total
推理
w
576
Pythonスクリプトの呼び出しと比較すると、合計1965の呼び出しが必要です。
質問
この実装は具体的ですか?つまり、Pythonの代わりにC / C ++でコードを書くと、
read
より多くの呼び出しが発生しますか?使用しているプログラムやツールの複雑さに応じて呼び出しが増加しますか?相関関係がありますか?
スクリプトを実行するよりもスクリプトを実行すると、より多くのエラーが発生するのはなぜですか
w
?
ノート
- ここのPythonスクリプトは印刷する単純なループです。確認する文字列で10回、複雑ではありません。 (コードは含まれていません。ビール)
答え1
システムコールは言語に依存しません。アセンブリ言語でツールを簡単に作成できます。ゆっくりシステムコールを使用するのが非効率的であれば、高級言語で実装するよりも優れています。これを説明する洗練されたが簡単な例は次のとおりです。
$ strace -c perl -e 'print "A"x9999' >/dev/null
...
100.00 0.000026 224 23 total
$ strace -c ./max >/dev/null
...
100.00 0.000430 10000 total
./max
以下のLinux用IA-64アセンブラはどこにありますか?
SECTION .text
Message: db "A"
global _start
_start:
mov r9,9999
_again:
mov rax,1 ; sys_write
mov rdi,1 ; stdout
mov rsi,Message
mov rdx,1
syscall
dec r9
jnz _again
_finish:
mov rax,60 ; sys_exit
mov rdi,0 ; exit code
syscall
コンパイルして
$ nasm -f elf64 -o max.o max.asm ; ld -o max max.o
プログラム〜しなければならない直接比較が有効になるように同じことを行います。
sys_read
通話は一般的に使用されるツールの複雑さに応じて増加する可能性がありますが、利用(入力のインポート)sys_write
(出力の解放)の後に、可能な限り実行される非常に複雑なニューラルネットワークの逆説的なケースを設計できますsys_exit
。システムコールの数と「複雑さ」(おそらくコード行?)を分析し、傾向があるかどうかを調べるためにプロットを描くことができるようです。 (「unikernel」を読むと、複雑さの議論に関する情報を得ることができます。)
エラー列は、stdoutを閉じてからそれを記録するエントリを呼び出すことによって示されるように、エラーの数です。これは明らかに失敗します。
$ strace -c ./max >&-
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
100.00 0.000427 0 9999 9999 write
0.00 0.000000 0 1 execve
------ ----------- ----------- --------- --------- ----------------
100.00 0.000427 10000 9999 total