커널 실행에서 지원되는 시스템 호출 또는 목록을

현재 실행중인 Linux Kernel에서 지원하는 시스템 호출 수 또는 목록을 얻는 방법이 있습니까? 따라서 실행중인 커널의 syscall 테이블을 ‘읽는’방법을 찾고 싶습니다.



답변

이 파일 /proc/kallsyms은 실행중인 커널의 모든 기호를 나열합니다. 관례 적으로 시스템 호출의 이름은로 시작합니다 sys_. 64 비트 시스템에서 32 비트 프로그램에 대한 시스템 호출의 이름은로 시작합니다 sys32_. 엄밀히 말하면, 이것은 시스템 호출이 아닌 내부 커널 함수를 나열하지만, ​​통신이 작동한다고 생각합니다 (모든 시스템 호출은 작업을 수행하기 위해 내부 커널 함수를 호출하며 이름은 항상 sys_앞에 붙은 시스템 호출의 이름이라고 생각합니다 ).

</proc/kallsyms sed -n 's/.* sys_//p'

시스템 호출은 매우 느리게 변경되므로 일반적으로 유용한 정보는 아닙니다. 선택적 구성 요소 (와 같은 장치로 일반적인 기능을 사용하여, 기존의 시스템 콜의 측면에서 기능을 제공 IOCTLread 하고 write당신에게 기능에 대해 아무것도 말하지 않을 것이다 지원 시스템 콜의 목록을 결정, 파일 시스템, 소켓 등을 잘라하지 않습니다) 시스템이 지원하는 다른 내부 함수 이름은 매우 빠르게 변경되기 때문에 도움이되지 않습니다. 한 커널 버전에서 일부 기능을 구현하는 함수 이름은 다음 버전에서 변경 될 수 있습니다.


답변

TL; DR

나는이 답변을 쓸 때 새로운 대안을 계속 찾았으므로 각 질문에 대해 약간의 세부 사항을 작성하고 통계를 작성했습니다. 기본적으로 다음 중 하나를 수행 할 수 있습니다.

  • 깨끗하고 빠른 방법을 제공하는 Gilles의 답변을 읽으십시오 (에 의존 /proc).
  • 설명서 리소스를 사용하십시오.
  • 시스템의 C 헤더 파일을 사용하십시오.
  • 커널 소스 코드 자체를 사용하십시오.
  • /sys디렉토리를 사용하십시오 .

수학을 한 후에 /sys파일 시스템을 사용하는 것이 좋습니다 . 시스템 호출 수 측면에서 최상의 결과를 제공하는 것 같습니다. 다른 트릭에 대해 읽고 싶지 않다면 해당 섹션으로 바로 이동할 수 있습니다.

설명서 리소스 사용

그 중 일부를 놓칠 수도 있지만 apropos섹션 2 (시스템 호출)에 속하는 모든 맨 페이지를 나열 하는 데 사용할 수 있습니다 .

$ apropos -s2 . | awk '{print $1}' | column

column멋진 열 출력을 원하지 않으면 제거하십시오 .

방금 찾았지만 시스템 호출에 대한 Linux 매뉴얼 페이지가 있으며 대부분의 시스템 호출을 찾을 수 있습니다.

$ man syscalls

나는 또한 흥미로운 두 웹 사이트를 발견했다.

헤더 파일 사용

편집 : 사용 가능한 시스템 호출을 결정하는 프로그래밍 방식으로 (또는 적어도 문서화 된 기능에 의존하지 않고) 커널이 시스템 호출 테이블을 최소한의 형태로 유지하지 않을까 걱정됩니다. 문자열 목록 (아마도 문자열을 조작 할 것으로 예상 됨). 이 수준에서는 함수 이름이 아닌 함수 주소와 포인터에 대해 더 많이 이야기하고 있습니다.

방금 내 /usr/include디렉토리를 탐색 grep하고 몇 가지 사항을 탐색했습니다 . 다음 디렉토리가 흥미로울 수 있습니다. 아키텍처와 배포판에 따라 일부 컴퓨터에서 다를 수 있지만 조정할 수있을 것입니다.

  • / usr / include / linux
  • / usr / include / x86_64-linux-gnu
  • / usr / include / sys
  • / usr / include / asm-generic

이 파일에서 함수 정의를 찾아 보면 시스템 정의가 완전히 정의되지 않았더라도 많은 시스템 호출을 보게됩니다. 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 ')'

커널의 소스 코드와 syscall 테이블 사용

또 다른 해결책은 커널 소스 코드 자체 (헤더뿐만 아니라)를 사용하고 효율적으로 검색하는 방법을 찾는 것입니다. 커널 커밋 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

당신은 사용 방법을 찾을 수 unamearch다운로드하기 tbl에서 파일 바로 git.kernel.org 실행중인 커널 버전 및 아키텍처에 기반을.

/sys파일 시스템 사용

Gilles의 대답은 나에게 약간의 영감을 주었고, 당신은 그 시스템 호출을 내부에서 찾을 수 있습니다 /sys/kernel/debug/tracing/events/syscalls. 이 디렉토리는 시스템에서 각 시스템 호출의 사용을 모니터하는 데 사용됩니다. 각 syscall에는 두 개의 디렉토리가 있습니다.

  • sys_enter_ [syscall]
  • sys_exit_ [syscall]

따라서, 사용 ls, grepcut

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

통계

내 시스템에서 :

  • 매뉴얼 페이지를 사용하여 440 개의 시스템 호출이 나타났습니다.
  • grep대한 -ing __SYSCALL헤더 파일의 212 시스템 호출을 밝혔다.
  • 커널 소스에서 syscalls 테이블을 읽으면 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는 가장 가까운 솔루션 인 것 같습니다).


답변

모든 대답은 괜찮습니다.

특정 시스템 호출 이름을 찾고있는 경우 :

$ cat /proc/kallsyms | grep <sys_call_name>

모든 시스템 호출 목록을 찾고있는 경우 :

$ cat /proc/kallsyms