Giới thiệu
Trong lab này, chúng ta sẽ khám phá lệnh strace của Linux và học cách sử dụng nó để theo dõi và giám sát các system call được thực hiện bởi một tiến trình đang chạy. Lệnh strace là một công cụ mạnh mẽ cung cấp những hiểu biết có giá trị về hoạt động bên trong của các chương trình, điều này có thể rất quan trọng để gỡ lỗi và khắc phục sự cố. Chúng ta sẽ bắt đầu bằng cách giới thiệu lệnh strace, sau đó đi sâu hơn vào việc theo dõi system call và cuối cùng khám phá cách sử dụng strace để gỡ lỗi các tiến trình. Lab này sẽ trang bị cho bạn các kỹ năng để sử dụng hiệu quả lệnh strace trong các tác vụ systemadmin và phát triển hệ thống Linux của bạn.
Giới thiệu về lệnh strace
Trong bước này, chúng ta sẽ khám phá lệnh strace, một công cụ mạnh mẽ trong Linux cho phép bạn theo dõi và giám sát các system call được thực hiện bởi một tiến trình đang chạy. System call là giao diện giữa một tiến trình và hệ điều hành, và việc hiểu chúng có thể rất quan trọng để gỡ lỗi và khắc phục sự cố.
Hãy bắt đầu bằng cách cài đặt gói strace:
sudo apt-get update
sudo apt-get install -y strace
Ví dụ về đầu ra:
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
libunwind8
Suggested packages:
fakeroot
The following NEW packages will be installed:
libunwind8 strace
0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
Need to get 292 kB of archives.
After this operation, 1,054 kB of additional disk space will be used.
Do you want to continue? [Y/n] Y
...
Bây giờ, hãy thử sử dụng lệnh strace để theo dõi một chương trình đơn giản. Chúng ta sẽ sử dụng lệnh ls
làm ví dụ:
strace ls
Ví dụ về đầu ra:
execve("/usr/bin/ls", ["ls"], 0x7ffee4f7a0f0 /* 23 vars */) = 0
brk(NULL) = 0x55b7d6c23000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
...
Đầu ra hiển thị chuỗi các system call được thực hiện bởi lệnh ls
, bao gồm execve
để thực thi lệnh, brk
để cấp phát bộ nhớ, access
để kiểm tra quyền truy cập tệp và openat
để mở tệp bộ nhớ đệm liên kết động.
Bằng cách phân tích đầu ra strace, bạn có thể hiểu rõ hơn về cách một chương trình tương tác với hệ điều hành, điều này có thể hữu ích cho việc gỡ lỗi và hiểu hành vi của chương trình.
Theo dõi System Call với strace
Trong bước này, chúng ta sẽ đi sâu hơn vào việc sử dụng lệnh strace để theo dõi các system call được thực hiện bởi một tiến trình đang chạy.
Hãy bắt đầu bằng cách tạo một tập lệnh Python đơn giản mà chúng ta có thể sử dụng để theo dõi:
cat > ~/project/example.py << EOF
import time
print("Hello, World!")
time.sleep(5)
EOF
Bây giờ, hãy theo dõi việc thực thi tập lệnh này bằng strace:
strace python ~/project/example.py
Ví dụ về đầu ra:
execve("/usr/bin/python", ["python", "/home/labex/project/example.py"], 0x7ffee4f7a0f0 /* 23 vars */) = 0
brk(NULL) = 0x55b7d6c23000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
...
write(1, "Hello, World!\n", 14) = 14
time(NULL) = 1618304400
nanosleep({5, 0}, NULL) = 0
exit_group(0) = ?
+++ exited with 0 +++
Đầu ra hiển thị chuỗi các system call được thực hiện bởi tập lệnh Python, bao gồm execve
để thực thi trình thông dịch Python, write
để xuất thông báo "Hello, World!", time
để lấy thời gian hiện tại và nanosleep
để tạm dừng tập lệnh trong 5 giây.
Bạn có thể sử dụng đầu ra strace để hiểu cách chương trình của bạn tương tác với hệ điều hành và xác định bất kỳ sự cố tiềm ẩn hoặc tắc nghẽn hiệu suất nào.
Hãy thử một ví dụ khác, lần này theo dõi việc thực thi lệnh ls
với một số tùy chọn bổ sung:
strace -c ls -l ~/project
Ví dụ về đầu ra:
total 4
-rw-r--r-- 1 labex labex 59 Apr 12 13:33 example.py
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
45.45 0.000005 5 1 execve
27.27 0.000003 3 1 brk
9.09 0.000001 1 1 access
9.09 0.000001 1 1 openat
9.09 0.000001 1 1 close
0.00 0.000000 0 4 read
0.00 0.000000 0 2 fstat
0.00 0.000000 0 1 mmap
0.00 0.000000 0 1 mprotect
0.00 0.000000 0 1 munmap
0.00 0.000000 0 2 ioctl
0.00 0.000000 0 1 statfs
0.00 0.000000 0 1 access
0.00 0.000000 0 2 newfstatat
0.00 0.000000 0 2 close
------ ----------- ----------- --------- --------- ----------------
100.00 0.000011 22 total
Trong ví dụ này, chúng ta đã sử dụng tùy chọn -c
để nhận được bản tóm tắt về các system call được thực hiện bởi lệnh ls
. Đầu ra hiển thị tỷ lệ phần trăm thời gian dành cho mỗi system call, số lượng cuộc gọi và số lượng lỗi.
Thông tin này có thể hữu ích để xác định tắc nghẽn hiệu suất hoặc hiểu hành vi của một chương trình.
Gỡ lỗi tiến trình với strace
Trong bước này, chúng ta sẽ học cách sử dụng lệnh strace để gỡ lỗi các tiến trình đang chạy và xác định các vấn đề tiềm ẩn.
Hãy bắt đầu bằng cách tạo một chương trình C đơn giản mà chúng ta có thể sử dụng để gỡ lỗi:
cat > ~/project/example.c << EOF
#include <stdio.h>
#include <unistd.h>
int main() {
printf("Hello, World!\n");
sleep(5);
return 0;
}
EOF
Bây giờ, hãy biên dịch chương trình và chạy nó với strace:
gcc -o ~/project/example ~/project/example.c
strace ~/project/example
Ví dụ về đầu ra:
execve("/home/labex/project/example", ["/home/labex/project/example"], 0x7ffee4f7a0f0 /* 23 vars */) = 0
brk(NULL) = 0x55b7d6c23000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
...
write(1, "Hello, World!\n", 14) = 14
time(NULL) = 1618304400
sleep(5) = 5
exit_group(0) = ?
+++ exited with 0 +++
Đầu ra hiển thị chuỗi các system call được thực hiện bởi chương trình C, bao gồm execve
để thực thi chương trình, write
để xuất thông báo "Hello, World!" và sleep
để tạm dừng chương trình trong 5 giây.
Bây giờ, giả sử chúng ta muốn gỡ lỗi một sự cố với chương trình. Chúng ta có thể sử dụng strace để xác định vấn đề. Ví dụ: giả sử chương trình không ghi đầu ra dự kiến vào một tệp. Chúng ta có thể theo dõi các system call liên quan đến tệp để xem điều gì đang xảy ra:
strace -e trace=file ~/project/example
Ví dụ về đầu ra:
execve("/home/labex/project/example", ["/home/labex/project/example"], 0x7ffee4f7a0f0 /* 23 vars */) = 0
write(1, "Hello, World!\n", 14) = 14
time(NULL) = 1618304400
sleep(5) = 5
exit_group(0) = ?
+++ exited with 0 +++
Đầu ra cho thấy rằng chương trình không thực hiện bất kỳ system call nào liên quan đến tệp, điều này cho thấy vấn đề không liên quan đến các thao tác tệp.
Bằng cách sử dụng strace để theo dõi các system call cụ thể hoặc toàn bộ hoạt động system call, bạn thường có thể xác định nguyên nhân gốc rễ của các sự cố trong chương trình của mình và gỡ lỗi chúng hiệu quả hơn.
Tóm tắt
Trong lab này, chúng ta đã khám phá lệnh strace mạnh mẽ của Linux, cho phép chúng ta theo dõi và giám sát các system call được thực hiện bởi một tiến trình đang chạy. Chúng ta bắt đầu bằng cách giới thiệu lệnh strace và cài đặt nó trên hệ thống của mình. Sau đó, chúng ta đã sử dụng strace để theo dõi các system call được thực hiện bởi lệnh ls
đơn giản, thu được những hiểu biết sâu sắc về cách chương trình tương tác với hệ điều hành. Tiếp theo, chúng ta đi sâu hơn vào việc sử dụng strace để theo dõi system call, tạo một tập lệnh Python đơn giản và quan sát chuỗi các system call mà nó thực hiện. Bằng cách phân tích đầu ra strace, chúng ta có thể hiểu rõ hơn về hành vi của chương trình và gỡ lỗi các sự cố có thể phát sinh.