มีวิธีรับจำนวนหรือรายการการโทรของระบบที่รองรับโดย Linux Kernel หรือไม่? ดังนั้นฉันต้องการหาวิธี 'อ่าน' ตาราง syscall ของเคอร์เนลที่กำลังทำงานอยู่
มีวิธีรับจำนวนหรือรายการการโทรของระบบที่รองรับโดย Linux Kernel หรือไม่? ดังนั้นฉันต้องการหาวิธี 'อ่าน' ตาราง syscall ของเคอร์เนลที่กำลังทำงานอยู่
คำตอบ:
แฟ้ม/proc/kallsyms
รายชื่อทั้งหมดของสัญลักษณ์ของเคอร์เนลเรียกใช้ sys_
โดยการประชุมสายระบบที่มีชื่อขึ้นต้นด้วย บนระบบ 64 บิตระบบเรียกร้องให้โปรแกรม 32 sys32_
บิตที่มีชื่อขึ้นต้นด้วย พูดอย่างเคร่งครัดรายการนี้เคอร์เนลฟังก์ชันภายในไม่เรียกระบบ แต่ผมคิดว่าการติดต่อไม่ทำงาน (ทุกสายระบบเรียกใช้ฟังก์ชันเคอร์เนลภายในงานที่ต้องทำและฉันคิดว่าชื่ออยู่เสมอชื่อเรียกระบบที่มีsys_
ใช้ได้ )
</proc/kallsyms sed -n 's/.* sys_//p'
นี่เป็นข้อมูลที่ไม่มีประโยชน์เนื่องจากการโทรของระบบเปลี่ยนไปช้ามาก ส่วนประกอบเสริมให้การทำงานในแง่ของการเรียกใช้ระบบที่มีอยู่โดยใช้คุณสมบัติทั่วไปเช่นอุปกรณ์ (ด้วยioctlเมื่อread
และwrite
ไม่ตัดมัน) ระบบไฟล์ซ็อกเก็ต ฯลฯ การกำหนดรายการ syscalls ที่รองรับจะไม่บอกอะไรเกี่ยวกับคุณสมบัติ ที่ระบบรองรับ ชื่อฟังก์ชั่นภายในอื่น ๆ จะไม่ช่วยอย่างใดอย่างหนึ่งเนื่องจากการเปลี่ยนแปลงเหล่านี้อย่างรวดเร็ว: ชื่อของฟังก์ชั่นที่ใช้คุณสมบัติบางอย่างในหนึ่งรุ่นเคอร์เนลอาจมีการเปลี่ยนแปลงในรุ่นต่อไป
ฉันหาทางเลือกใหม่ ๆ เสมอเมื่อเขียนคำตอบนี้ดังนั้นฉันจึงเขียนรายละเอียดเล็กน้อยเกี่ยวกับพวกเขาแต่ละคนและสร้างสถิติ โดยทั่วไปคุณสามารถ:
/proc
)/sys
ไดเรกทอรีหลังจากทำคณิตศาสตร์ฉันแนะนำ (ในทางเลือกของฉัน) โดยใช้/sys
ระบบไฟล์เนื่องจากดูเหมือนว่าจะให้ผลลัพธ์ที่ดีที่สุดในแง่ของจำนวนการโทรของระบบ คุณอาจกระโดดไปทางขวาในส่วนนั้นหากคุณไม่ต้องการอ่านเกี่ยวกับลูกเล่นอื่น ๆ
ในขณะที่คุณอาจพลาดบางส่วนคุณสามารถใช้apropos
เพื่อแสดงรายการ manpages ทั้งหมดที่อยู่ในส่วนที่ 2 (การเรียกระบบ)
$ apropos -s2 . | awk '{print $1}' | column
ลบออกcolumn
หากคุณไม่ต้องการให้เอาต์พุตคอลัมน์แบบแฟนซี
ฉันเพิ่งพบมัน แต่มีหน้าลินุกซ์เกี่ยวกับการโทรของระบบและคุณจะสามารถค้นหาพวกเขาส่วนใหญ่ในนั้น
$ man syscalls
ฉันเจอเว็บไซต์ทั้งสองนี้ซึ่งน่าสนใจ:
แก้ไข:ตอนนี้เมื่อมาถึงโปรแกรม (หรืออย่างน้อยโดยไม่ต้องอาศัยคุณสมบัติเอกสาร) กำหนดสายระบบที่มีอยู่ฉันกลัวเคอร์เนลไม่เก็บตารางการโทรระบบอย่างน้อยไม่อยู่ภายใต้รูปแบบของ รายการสตริง (ตามที่คุณคาดว่าจะจัดการได้) ในระดับนี้เรากำลังพูดถึงฟังก์ชันที่อยู่และพอยน์เตอร์มากกว่าชื่อฟังก์ชั่น
ฉันเพิ่งเรียกดู/usr/include
ไดเรกทอรีของฉันและgrep
ทำบางสิ่ง: คุณอาจพบว่าไดเรกทอรีต่อไปนี้น่าสนใจ บางส่วนอาจแตกต่างกันไปในเครื่องของคุณขึ้นอยู่กับสถาปัตยกรรมและการกระจายของคุณ แต่ฉันแน่ใจว่าคุณจะสามารถปรับเปลี่ยนได้
เมื่อมองหาคำจำกัดความของฟังก์ชั่นในไฟล์นี้คุณจะพบกับการเรียกใช้ระบบจำนวนมากแม้ว่าจะไม่ได้นิยามไว้อย่างสมบูรณ์ ฉันวิ่งไปหลายgrep
ๆ ไดเรกทอรีในไดเรกทอรีเหล่านี้และฉันสามารถค้นหาการกล่าวถึงการเรียกของระบบ นี่คือตัวอย่าง:
$ grep 'sys_exit' /usr/include -R
asm-generic/unistd.h:__SYSCALL(__NR_exit, sys_exit)
ดังนั้นฉันเดาอีกวิธีหนึ่งในการค้นหาบางคนจะเป็น:
$ egrep '^__SYSCALL' /usr/include -Rh | awk '{print $2}' | tr -d ')'
อีกวิธีคือใช้ซอร์สโค้ดของเคอร์เนลเอง (ไม่ใช่เฉพาะส่วนหัว!) และค้นหาวิธีการค้นหาอย่างมีประสิทธิภาพ เนื่องจากเคอร์เนลใช้ 303395ac3bf3e2cb488435537d416bc840438fcbคุณอาจพบว่านี่ง่ายกว่านี้เล็กน้อย นี่คือตัวอย่างสำหรับ 3.13 (ซึ่งเป็นเคอร์เนลของฉัน):
$ 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
ตอนนี้คุณได้รับตาราง syscalls จริงเพียงแค่เรียกดู:
$ while read line; do awk '! /#/ {print $3}'; done < syscall_64.tbl
คุณสามารถหาวิธีใช้uname
และarch
เพื่อดาวน์โหลดtbl
ไฟล์ได้โดยตรงจากgit.kernel.orgโดยใช้เวอร์ชันและสถาปัตยกรรมเคอร์เนลที่รันอยู่
/sys
ระบบไฟล์คำตอบที่กิลส์ให้ฉันนิด ๆ หน่อย ๆ /sys/kernel/debug/tracing/events/syscalls
ของแรงบันดาลใจและคุณอาจพบว่าผู้ที่สายระบบภายใน ไดเร็กทอรีนี้ใช้เพื่อมอนิเตอร์การใช้การเรียกระบบแต่ละครั้งบนระบบ syscall แต่ละอันมีสองไดเรกทอรีอยู่ในนั้น:
ดังนั้นการใช้ls
, grep
และcut
...
$ ls /sys/kernel/debug/tracing/events/syscalls | grep 'sys_enter' | cut -d'_' -f3
ในระบบของฉัน:
grep
-ing สำหรับ__SYSCALL
ในไฟล์ส่วนหัวเปิดเผยการเรียกระบบ 212/sys
เปิดเผยสายระบบ 290ตอนนี้ถ้าฉันรวบรวมทุกอย่าง ...
$ 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
ไปแล้ว 707 สายระบบ! แน่นอนว่าตัวเลขนี้แสดงถึงคำจำกัดความที่ยืดหยุ่นอย่างมากของ "การเรียกของระบบ" เนื่องจาก3.13 ควรจะให้การเรียกใช้ระบบ 274 เท่านั้น (การอ่าน/sys
น่าจะเป็นทางออกที่ใกล้เคียงที่สุด)
คำตอบทั้งหมดเป็นเรื่องปกติ
หากคุณกำลังมองหาชื่อการโทรของระบบเฉพาะ:
$ cat /proc/kallsyms | grep <sys_call_name>
หากคุณกำลังมองหารายการการโทรระบบทั้งหมด:
$ cat /proc/kallsyms
/proc/kallsyms
สามารถจัดการได้เหมือนกับไฟล์อื่น ๆ มันจึงค่อนข้างใช้งานได้ง่ายในโปรแกรม