Câu trả lời:
Các tập tin /proc/kallsyms
liệt kê tất cả các biểu tượng của hạt nhân đang chạy. Theo quy ước, các cuộc gọi hệ thống có một tên bắt đầu bằng sys_
. Trên hệ thống 64 bit, các cuộc gọi hệ thống cho các chương trình 32 bit có tên bắt đầu bằng sys32_
. Nói một cách chính xác, điều này liệt kê các hàm kernel bên trong, không phải là cuộc gọi hệ thống, nhưng tôi nghĩ rằng sự tương ứng có tác dụng (mọi cuộc gọi hệ thống đều gọi một hàm kernel bên trong để thực hiện công việc và tôi nghĩ rằng tên luôn là tên của cuộc gọi hệ thống được đặt sys_
trước ).
</proc/kallsyms sed -n 's/.* sys_//p'
Đây thường không phải là thông tin hữu ích, vì các cuộc gọi hệ thống thay đổi rất chậm. Các thành phần tùy chọn cung cấp chức năng theo các cuộc gọi hệ thống hiện có, sử dụng các tính năng chung như thiết bị (với ioctl khi nào read
và write
không cắt nó), hệ thống tệp, ổ cắm, v.v. Xác định danh sách các tòa nhà được hỗ trợ sẽ không cho bạn biết bất cứ điều gì về các tính năng mà hệ thống hỗ trợ. Các tên hàm nội bộ khác sẽ không giúp được gì vì chúng thay đổi rất nhanh: tên của hàm thực hiện một số tính năng trên một phiên bản kernel có thể thay đổi trên phiên bản tiếp theo.
Tôi tiếp tục tìm giải pháp thay thế mới khi viết câu trả lời này, vì vậy tôi chỉ viết một chút chi tiết về từng câu hỏi và đưa ra một số thống kê. Về cơ bản, bạn có thể:
/proc
)./sys
thư mục.Sau khi thực hiện phép toán, tôi khuyên bạn nên (trong số các lựa chọn thay thế của mình) sử dụng /sys
hệ thống tệp, vì nó dường như mang lại kết quả tốt nhất về số lượng cuộc gọi hệ thống. Bạn có thể chuyển ngay sang phần đó nếu bạn không muốn đọc về các thủ thuật khác.
Mặc dù bạn có thể bỏ lỡ một số trong số chúng, bạn có thể sử dụng apropos
để liệt kê tất cả các trang thuộc về phần 2 (các cuộc gọi hệ thống):
$ apropos -s2 . | awk '{print $1}' | column
Xóa column
nếu bạn không muốn đầu ra cột ưa thích.
Tôi mới tìm thấy nó, nhưng có một trang Linux về các cuộc gọi hệ thống và bạn sẽ có thể tìm thấy hầu hết trong số đó.
$ man syscalls
Tôi cũng đã xem qua hai trang web này có thể thú vị:
Chỉnh sửa: Bây giờ, khi nói đến lập trình (hoặc ít nhất, không dựa vào các tính năng được ghi lại) xác định các cuộc gọi hệ thống nào khả dụng, tôi e rằng kernel không giữ bảng các cuộc gọi hệ thống của mình, ít nhất là không ở dạng một danh sách các chuỗi (như bạn có thể mong đợi để thao tác chúng). Ở cấp độ này, chúng ta đang nói nhiều hơn về địa chỉ hàm và con trỏ, thay vì tên hàm.
Tôi chỉ duyệt /usr/include
thư mục của mình và grep
-ed một vài điều: bạn có thể thấy các thư mục sau đây thú vị. Một số trong số chúng có thể khác nhau trên máy của bạn, tùy thuộc vào kiến trúc và phân phối của bạn, nhưng tôi chắc chắn bạn sẽ có thể điều chỉnh chúng.
Bằng cách tìm kiếm các định nghĩa hàm trong tệp này, bạn sẽ bắt gặp nhiều cuộc gọi hệ thống, mặc dù chúng sẽ không được xác định đầy đủ trong đó. Tôi đã chạy một vài grep
s trong các thư mục này và tôi đã có thể tìm thấy đề cập đến một số cuộc gọi hệ thống. Đây là một ví dụ:
$ grep 'sys_exit' /usr/include -R
asm-generic/unistd.h:__SYSCALL(__NR_exit, sys_exit)
Vì vậy, tôi đoán một cách khác để tìm một số trong số họ sẽ là:
$ egrep '^__SYSCALL' /usr/include -Rh | awk '{print $2}' | tr -d ')'
Một giải pháp khác là sử dụng chính mã nguồn kernel (và không chỉ các tiêu đề!) Và tìm cách tìm kiếm nó một cách hiệu quả. Vì kernel commit 303395ac3bf3e2cb488435537d416bc840438fcb , bạn có thể thấy việc này dễ hơn một chút so với trước đây. Đây là một ví dụ cho 3.13 (đó là kernel của tôi):
$ wget https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/plain/arch/x86/syscalls/syscall_64.tbl?id=refs/tags/v3.13 -O syscall_64.tbl
Bây giờ bạn đã có bảng tòa nhà thực tế, chỉ cần duyệt nó:
$ while read line; do awk '! /#/ {print $3}'; done < syscall_64.tbl
Bạn có thể tìm cách, sử dụng uname
và arch
, để tải xuống tbl
tệp trực tiếp từ git.kernel.org , dựa trên phiên bản và kiến trúc kernel đang chạy của bạn.
/sys
hệ thống tập tinCâu trả lời của Gilles đã cho tôi một chút cảm hứng, và bạn có thể tìm thấy những cuộc gọi hệ thống đó bên trong /sys/kernel/debug/tracing/events/syscalls
. Thư mục này được sử dụng để theo dõi việc sử dụng từng cuộc gọi hệ thống trên hệ thống. Mỗi tòa nhà có hai thư mục trong đó:
Vì vậy, sử dụng ls
, grep
và cut
...
$ ls /sys/kernel/debug/tracing/events/syscalls | grep 'sys_enter' | cut -d'_' -f3
Trên hệ thống của tôi:
grep
-ing cho __SYSCALL
trong các tập tin tiêu đề tiết lộ 212 cuộc gọi hệ thống./sys
tiết lộ 290 cuộc gọi hệ thống.Bây giờ, nếu tôi mang mọi thứ lại với nhau ...
$ apropos -s2 . | awk '{print $1}' > system_calls.txt
$ egrep '^__SYSCALL' /usr/include -Rh | awk '{print $2}' | tr -d ')' >> system_calls.txt
$ while read line; do awk '! /#/ {print $3}'; done < syscall_64.tbl >> system_calls.txt
$ ls /sys/kernel/debug/tracing/events/syscalls | grep 'sys_enter' | cut -d'_' -f3 >> system_calls.txt
$ sort < system_calls.txt | uniq | wc -l
707
Chúng tôi đi, 707 cuộc gọi hệ thống! Tất nhiên, con số này phản ánh một định nghĩa rất linh hoạt về "cuộc gọi hệ thống", vì 3.13 được cho là chỉ cung cấp 274 cuộc gọi hệ thống (đọc /sys
dường như là giải pháp gần nhất).
Tất cả các câu trả lời là tốt.
Nếu bạn đang tìm kiếm một tên gọi hệ thống cụ thể:
$ cat /proc/kallsyms | grep <sys_call_name>
Nếu bạn đang tìm kiếm danh sách tất cả các cuộc gọi hệ thống:
$ cat /proc/kallsyms
/proc/kallsyms
có thể được thao tác như bất kỳ tệp nào khác, nên việc sử dụng nó trong một chương trình trở nên khá dễ dàng.