깊이 다이빙하고 싶어리눅스항상 사용할 수 있는 더 많은 훌륭한 도구strace
(버전: 4.11) 존재하다우분투 16.04 LTS아래와 같이 이름이 붙은 이유가 궁금합니다.
# strace -c w
단순한 시스템 호출 이상의 것이 필요합니다.파이썬문자열을 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