Các cuộc gọi hệ thống được hỗ trợ trong việc chạy Kernel


9

Có cách nào để có được số lượng hoặc danh sách các cuộc gọi hệ thống được hỗ trợ bởi Linux Kernel hiện đang chạy không? Vì vậy, tôi muốn tìm cách 'đọc' bảng tòa nhà của một hạt nhân đang chạy.

Câu trả lời:


15

Các tập tin /proc/kallsymsliệ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 readwritekhô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.


+1. Bây giờ đó là những gì tôi muốn nói khi tôi nói "Tôi sẽ để người có nhiều kinh nghiệm hơn tôi trả lời bạn" . Ngoài ra, vì /proc/kallsymscó 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.
John WH Smith

2
@JohnWHSmith Triệu Có thể được thao tác như bất kỳ tập tin nào khác.
Gilles 'SO- ngừng trở nên xấu xa'

7

TL; DR

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ể:

  • Đọc câu trả lời của Gilles, cung cấp một cách nhanh chóng và sạch sẽ để làm điều đó (dựa vào /proc).
  • Sử dụng các tài liệu tài liệu.
  • Sử dụng tệp tiêu đề C của hệ thống của bạn.
  • Sử dụng mã nguồn kernel.
  • Sử dụng /systhư 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 /syshệ 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.

Sử dụng tài nguyên tài liệu

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 columnnế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ị:

Sử dụng tập tin tiêu đề

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/includethư 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.

  • / usr / bao gồm / linux
  • / usr / bao gồm / x86_64-linux-gnu
  • / usr / bao gồm / sys
  • / usr / bao gồm / asm-generic

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 greps 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 ')'

Sử dụng mã nguồn của kernel và bảng tòa nhà của nó

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 unamearch, để tải xuống tbltệ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.

Sử dụng /syshệ thống tập tin

Câ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 đó:

  • sys_enter_ [tòa nhà cao tầng]
  • sys_exit_ [tòa nhà cao tầng]

Vì vậy, sử dụng ls, grepcut...

$ ls /sys/kernel/debug/tracing/events/syscalls | grep 'sys_enter' | cut -d'_' -f3

Số liệu thống kê

Trên hệ thống của tôi:

  • Sử dụng các trang người đàn ông tiết lộ 440 cuộc gọi hệ thống.
  • grep-ing cho __SYSCALLtrong các tập tin tiêu đề tiết lộ 212 cuộc gọi hệ thống.
  • Đọc bảng tòa nhà từ các nguồn kernel đã tiết lộ 346 cuộc gọi hệ thống.
  • Sử dụng /systiế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 /sysdường như là giải pháp gần nhất).


Tôi đang tìm kiếm một cách nhiều hơn về 'đọc' bảng gọi hệ thống theo một cách nào đó thay vì tìm ra các cuộc gọi hệ thống nào được ghi lại trong các trang man
Swair

Tôi không nghĩ rằng kernel giữ một danh sách các tòa nhà của nó, ít nhất không phải là một danh sách các chuỗi. Tôi chỉnh sửa câu trả lời của tôi. Nếu có một cách thực tế để làm điều này, tôi sẽ để người có nhiều kinh nghiệm hơn tôi trả lời bạn;)
John WH Smith

Vì vậy, tôi đã tự hỏi về điều này sau khi tôi thêm một cuộc gọi hệ thống vào kernel và cố gắng sử dụng nó đang đưa ra "chức năng không được thực hiện", và tôi tự hỏi liệu có cách nào để lấy bảng sallall cho kernel hiện tại không. Khi tôi thực hiện '#make install', cập nhật grub và khởi động kernel mới, ở bước nào thì kernel mới có liên quan bao gồm các tệp có chứa lệnh gọi hệ thống mới?
Swair

1
Nếu cuộc gọi hệ thống của bạn không được tìm thấy, thì bạn đã không thực hiện đúng. Câu trả lời của tôi cho bạn biết cách tìm các cuộc gọi hệ thống của Linux, nhưng không phải là cách gỡ lỗi của riêng bạn (vì đó không phải là điều bạn đang yêu cầu). Nếu bạn gặp khó khăn trong việc phát triển nó, bạn nên đặt câu hỏi cụ thể về nó và tránh vấn đề XY .
John WH Smith

@swair Rất bất thường khi thêm chức năng bằng cách thêm một cuộc gọi hệ thống. Chúng tôi không thể chắc chắn điều gì sai vì bạn đã không cung cấp bất kỳ mã nào (và nếu câu hỏi của bạn yêu cầu mã C, thì nó không có chủ đề ở đây, nhưng ở nhà trên Stack Overflow ). Tôi nghi ngờ rằng bạn đã thực hiện một cuộc gọi hệ thống (chính xác hay không) và bạn đang cố gắng sử dụng nó từ một chương trình C và rằng bạn đang thiếu bước viết một hàm C thực hiện cuộc gọi hệ thống. Một cuộc gọi hệ thống không phải là một cuộc gọi chức năng thông thường.
Gilles 'SO- ngừng trở nên xấu xa'

1

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.