현재 실행 중인 Linux 커널이 지원하는 시스템 호출 수나 목록을 얻을 수 있는 방법이 있습니까? 그래서 나는 실행 중인 커널의 시스템 호출 테이블을 "읽는" 방법을 찾고 싶습니다.
답변1
이 파일은 /proc/kallsyms
실행 중인 커널의 모든 기호를 나열합니다. 관례적으로 시스템 호출 이름은 sys_
. 64비트 시스템에서는 32비트 프로그램에 대한 시스템 호출 이름이 sys32_
. 내 생각에 이름은 항상 sys_
접두사가 붙은 시스템 호출의 이름인 것 같습니다.
</proc/kallsyms sed -n 's/.* sys_//p'
시스템 호출이 매우 느리게 변경되기 때문에 이는 일반적으로 유용한 정보가 아닙니다. 선택적 구성 요소는 기존 시스템 호출에 기능을 제공하고 장치(I/W 제어지원되는 시스템 호출 목록을 결정한다고 해서 시스템이 지원하는 기능에 대해서는 아무 것도 알 수 없습니다 read
. write
다른 내부 함수 이름도 매우 빠르게 변경되기 때문에 도움이 되지 않습니다. 한 커널 버전에서 무언가를 구현하는 함수 이름이 다음 커널 버전에서 변경될 수 있습니다.
답변2
긴 이야기 짧게
이 답변을 작성하는 동안 저는 끊임없이 새로운 대안을 찾고 있었기 때문에 각 대안에 대한 세부 정보를 작성하고 통계를 작성했습니다. 기본적으로 다음을 수행할 수 있습니다.
- Gilles의 답변을 읽으면 깨끗하고 빠른 방법을 제공합니다(에 따라 다름
/proc
). - 문서 리소스를 사용하세요.
- 시스템의 C 헤더 파일을 사용하십시오.
- 커널 소스 코드 자체를 사용하십시오.
- 디렉토리를 사용하십시오
/sys
.
계산을 마친 후에는 /sys
시스템 호출 수 측면에서 최상의 결과를 제공하는 것처럼 보이는 파일 시스템을 사용하는 것이 좋습니다. 다른 팁을 읽고 싶지 않다면 이 섹션으로 바로 건너뛸 수 있습니다.
문서 리소스 사용
apropos
그 중 일부를 놓칠 수도 있지만 파트 2(시스템 호출)에 속하는 모든 맨페이지를 나열하는 맨페이지를 사용할 수 있습니다 .
$ apropos -s2 . | awk '{print $1}' | column
column
멋진 원주형 출력을 원하지 않으면 제거하세요.
방금 알아냈는데 시스템 호출에 관한 Linux 매뉴얼 페이지가 있고 거기에서 대부분을 찾을 수 있습니다.
$ man syscalls
또한 흥미로울 수 있는 다음 두 웹사이트를 발견했습니다.
헤더 파일 사용
편집하다:이제 어떤 시스템 호출이 사용 가능한지 프로그래밍 방식으로(또는 적어도 로깅 기능에 의존하지 않고) 결정할 때 커널이 시스템 호출 테이블을 적어도 목록 형식으로 유지하지 않는 것이 유감입니다. 문자열(조작할 것으로 예상할 수 있음) 이 수준에서는 함수 이름보다는 함수 주소와 포인터에 대해 더 많이 이야기합니다.
/usr/include
방금 내 카탈로그를 살펴보고 grep
몇 가지 사항을 추가했습니다. 다음 카탈로그가 흥미로울 것입니다. 이들 중 일부는 아키텍처와 배포판에 따라 컴퓨터에서 다를 수 있지만 적응할 수 있을 것이라고 확신합니다.
- /usr/include/리눅스
- /usr/include/x86_64-linux-gnu
- /usr/포함/시스템
- /usr/include/asm-일반
이 파일에서 함수 정의를 검색하면 완전히 정의되지 않은 경우에도 많은 시스템 호출을 만나게 됩니다. 나는 이 디렉토리에서 몇 가지를 실행했고 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
이제 실제 시스템 호출 테이블이 있으므로 찾아보기만 하면 됩니다.
$ while read line; do awk '! /#/ {print $3}'; done < syscall_64.tbl
사용 방법을 uname
직접 찾아보실 수 있습니다.arch
tbl
git.kernel.org, 실행 중인 커널 버전 및 아키텍처를 기반으로 합니다.
/sys
파일 시스템 사용
Gilles의 답변은 거기에서 어떤 시스템 호출을 찾을 수 있는지에 대해 나에게 약간의 영감을 주었습니다 /sys/kernel/debug/tracing/events/syscalls
. 이 디렉터리는 시스템의 다양한 시스템 호출 사용량을 모니터링하는 데 사용됩니다. 각 시스템 호출에는 두 개의 디렉터리가 있습니다.
- sys_enter_[시스템 호출]
- sys_exit_[시스템 호출]
따라서 , ls
및 grep
... cut
을 사용하십시오.
$ ls /sys/kernel/debug/tracing/events/syscalls | grep 'sys_enter' | cut -d'_' -f3
통계자료
내 시스템에서:
- 매뉴얼 페이지를 사용하여 440개의 시스템 호출을 찾았습니다.
grep
-ing for는__SYSCALL
헤더 파일에 212개의 시스템 호출을 표시합니다.- 커널 소스에서 시스템 호출 테이블을 읽으면 346개의 시스템 호출이 드러났습니다.
/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
가장 가까운 해결책인 것 같습니다).
답변3
모든 답변이 좋습니다.
특정 시스템 호출 이름을 찾고 있는 경우:
$ cat /proc/kallsyms | grep <sys_call_name>
모든 시스템 호출 목록을 찾고 있는 경우:
$ cat /proc/kallsyms