Bài 42.224 phút đọc
strace và chi phí syscall
Sau bài này bạn sẽ làm được
- Dùng strace để xem và thống kê syscall
- Phân biệt man mục 2 và mục 3
- Giải thích vì sao đọc từng byte chậm gấp nghìn lần
- Dùng ltrace để xem lời gọi thư viện
stracecho bạn xem mọi lời gọi hệ thống một chương trình thực hiện. Nó biến câu "chương trình nói gì với nhân" từ trừu tượng thành một danh sách đọc được, và là công cụ chẩn đoán mạnh nhất trên Linux.
#strace
terminal
# Xem MOI syscall cua mot chuong trinh
strace ./hello
execve("./hello", ["./hello"], 0x7ff...) = 0
brk(NULL) = 0x561...
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/.../libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF...", 832) = 832
mmap(NULL, 8192, PROT_READ|PROT_WRITE, ...) = 0x7f...
...
write(1, "xin chao\n", 9) = 9
exit_group(0) = ?#Thống kê -c
terminal
# -c: thong ke thay vi liet ke tung dong
strace -c ./perf 1
% time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 99.82 5.204831 0 20971520 read 0.10 0.005102 12 417 mmap 0.05 0.002431 9 260 write ------ ----------- ----------- --------- --------- ---------------- 100.00 5.213... 20972197 total
strace -c ./perf 65536
% time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 42.11 0.000198 0 320 read ... ------ ----------- ----------- --------- --------- ----------------
#Lọc và ltrace
strace -e trace=open,openat,read ./prog # chi cac syscall nay
strace -e trace=file ./prog # moi syscall lien quan tep
strace -e trace=network ./prog # moi syscall mang
strace -f ./prog # theo doi ca tien trinh CON (fork)
strace -p 1234 # gan vao tien trinh dang chay
strace -T ./prog # in thoi gian moi syscall
strace -o vet.txt ./prog # ghi ra tep thay vi man hinh
/* -f RAT huu ich voi chuong trinh dung fork (nhu shell): khong
co no, strace chi thay tien trinh cha, khong thay con exec gi. */#Các nhóm syscall
| Nhóm | Syscall tiêu biểu | Chương |
|---|---|---|
| Tệp | open, close, read, write, lseek, stat, unlink | 41 |
| Tiến trình | fork, execve, exit, wait4, kill, getpid | 40 |
| Bộ nhớ | mmap, munmap, brk, mprotect | 42.3 |
| IPC | pipe, socket, bind, listen, accept, connect | 43, 46 |
| Tín hiệu | signal, sigaction, sigprocmask | 44 |
| Thời gian | clock_gettime, nanosleep, gettimeofday | 42 |
| Ghép kênh | select, poll, epoll_wait | 46.9 |
Tự làm thử
- Chạy
stracetrên chương trình Hello World tĩnh và động, so số syscall. - Dùng
strace -cchứng minh đọc từng byte gọi nhiều read hơn đọc theo khối. - Dùng
strace -e openattìm mọi tệp một chương trình thử mở. - Gắn
strace -pvào một chương trình đang treo và tìm syscall nó đang kẹt. - Dùng
strace -ftheo dõi một chương trìnhforkcộngexec. - Dùng
ltraceđể đếm số lầnmallocmột chương trình gọi.
Trình chấm điểm tự động sẽ được bổ sung ở giai đoạn sau. Hiện tại bạn tự chạy thử trên máy.
Tóm tắt
straceliệt kê mọi syscall một chương trình gọi, kèm tham số và giá trị trả về, hiện cả tên mã lỗi.strace -cthống kê số lần gọi và thời gian, dùng để chứng minh bẫy hiệu năng thay vì đoán.- Lọc bằng
-e, theo con bằng-f, gắn tiến trình bằng-p;ltracexem lời gọi thư viện. man 2là syscall,man 3là hàm thư viện xây trên syscall.- Linux có vài trăm syscall nhưng bạn dùng vài chục; mọi thứ trong C xây trên chúng.