애플리케이션이 POSIX의 어떤 부분을 사용하고 있는지 어떻게 테스트합니까?

애플리케이션이 POSIX의 어떤 부분을 사용하고 있는지 어떻게 테스트합니까?

C 소스 코드를 얻었고 POSIX의 어떤 부분(함수, 시스템 호출)이 사용되는지 확인하고 싶습니다.

개요를 제공할 수 있는 테스트 모음이나 기타 프로그램이 있습니까?

답변1

코드를 컴파일하고 실행할 수 있고, 코드가 수행하는 sys 호출을 살펴보는 것만으로도 충분하다면(즉, 알아야 할 모든 것을 연습할 수 있습니다)

strace myapp

myapp모든 시스템 호출(POSIX 및 기타)을 실행 하고 나열합니다.

답변2

strace추적하다체계수신 전화. POSIX에는 두 가지가 모두 포함됩니다.체계수신 전화 및기능. 일부 플랫폼은 유사한 ltrace(추적도서관수신 전화).

예를 들어 date명령줄 유틸리티는 ltrace다음과 같이 표시됩니다.

__libc_start_main(0x401a50, 1, 0x7ffe41310418, 0x40a100, 0x40a0f0 <unfinished ...>
strrchr("date", '/')                             = NULL
setlocale(6, "")                                 = "en_US.UTF-8"
bindtextdomain("coreutils", "/usr/share/locale") = "/usr/share/locale"
textdomain("coreutils")                          = "coreutils"
__cxa_atexit(0x402b60, 0, 0, 0x736c6974756572, 0x7f8c29d9bea8) = 0
getenv("POSIXLY_CORRECT")                        = NULL
nl_langinfo(131180, 0x40b6b9, 0, 0, 0)           = 0x7f8c23e98955
clock_gettime(0, 0x7ffe41310260, 0x20ef440, 0, 0) = 0
localtime(0x7ffe413101d0)                        = 0x7f8c29d9f380
strftime("", 140239874654731, NULL, 0x7ffe4130fd63) = 4
fwrite("Mon", 3, 1, 0x7f8c29d9a7a0)              = 1
fputc(' ', 0x7f8c29d9a7a0)                       = 32
strftime("", 140239874654844, NULL, 0x7ffe4130fd63) = 4
fwrite("Sep", 3, 1, 0x7f8c29d9a7a0)              = 1
fputc(' ', 0x7f8c29d9a7a0)                       = 32
fwrite("12\004\200\0011A\376\177", 2, 1, 0x7f8c29d9a7a0) = 1
fputc(' ', 0x7f8c29d9a7a0)                       = 32
fwrite("17\004\200\0011A\376\177", 2, 1, 0x7f8c29d9a7a0) = 1
fputc(':', 0x7f8c29d9a7a0)                       = 58
fwrite("43\004\200\0011A\376\177", 2, 1, 0x7f8c29d9a7a0) = 1
fputc(':', 0x7f8c29d9a7a0)                       = 58
fwrite("52\004\200\0011A\376\177", 2, 1, 0x7f8c29d9a7a0) = 1
fputc(' ', 0x7f8c29d9a7a0)                       = 32
strlen("EDT")                                    = 3
fwrite("EDT", 3, 1, 0x7f8c29d9a7a0)              = 1
fputc(' ', 0x7f8c29d9a7a0)                       = 32
fwrite("2016\004\200\0011A\376\177", 4, 1, 0x7f8c29d9a7a0) = 1
__overflow(0x7f8c29d9a7a0, 10, 4, 54, 0x7f8c2a1c401c) = 10
exit(0 <unfinished ...>
...

strace다른 것을 표시하는 동안 :

execve("/bin/date", ["date"], [/* 60 vars */]) = 0
brk(0)                                  = 0x1ac9000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ff3eed91000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=132177, ...}) = 0
mmap(NULL, 132177, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7ff3eed70000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/librt.so.1", O_RDONLY) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\220!\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=31744, ...}) = 0
mmap(NULL, 2128856, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7ff3ee96c000
mprotect(0x7ff3ee973000, 2093056, PROT_NONE) = 0
mmap(0x7ff3eeb72000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x6000) = 0x7ff3eeb72000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\300\357\1\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1607696, ...}) = 0
mmap(NULL, 3721272, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7ff3ee5df000
mprotect(0x7ff3ee763000, 2093056, PROT_NONE) = 0
mmap(0x7ff3ee962000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x183000) = 0x7ff3ee962000
mmap(0x7ff3ee967000, 18488, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7ff3ee967000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0@\\\0\0\0\0\0\0"..., 832) = 832
...

두 경우 모두에 대해서만 예를 들었습니다. 그러나 두 개의 완전한 궤적을 비교한다면 둘 사이에 큰 상관관계를 찾을 수 없습니다. 항상 그런 것은 아닙니다. I/O를 수행하는 함수는 둘 사이에서 상당히 밀접하게 일치할 수 있습니다. 그러나 로그의 마지막 부분에만 strace로그와 일치할 수 있는 I/O가 표시됩니다 ltrace. 이 모든 호출 fwrite은 최종 시스템 호출 fputc까지 메모리 내 작업이 됩니다 .write

open("/usr/lib/locale/locale-archive", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=110939968, ...}) = 0
mmap(NULL, 110939968, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7ff3e79f6000
close(3)
open("/etc/localtime", O_RDONLY)        = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=3519, ...}) = 0
fstat(3, {st_mode=S_IFREG|0644, st_size=3519, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ff3eed90000
read(3, "TZif2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\0\0\0\4\0\0\0\0"..., 4096) = 3519
lseek(3, -2252, SEEK_CUR)               = 1267
read(3, "TZif2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\5\0\0\0\5\0\0\0\0"..., 4096) = 2252
close(3)                                = 0
munmap(0x7ff3eed90000, 4096)            = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ff3eed90000
write(1, "Mon Sep 12 17:43:41 EDT 2016\n", 29) = 29
close(1)                                = 0
munmap(0x7ff3eed90000, 4096)            = 0
close(2)                                = 0
exit_group(0)                           = ?

두 추적 모두에서 밑줄로 시작하는 이름은 확실히 POSIX가 아닙니다. 호출 과 같은 다른 것들도 구현에 따라 다릅니다 exit_group.

애플리케이션의 소스 코드가 없고 바이너리만 관찰할 수 있는 경우 이 접근 방식을 개선할 수 있는 실행 가능한 방법이 없습니다. POSIX는 애플리케이션 소스코드를 활용한 다양한 기능을 기반으로 한다. 예를 들어, 일부 기능은 애플리케이션이 컴파일되는 시스템 헤더 파일에 따라 달라지고, 다른 기능은 명령줄 유틸리티의 동작에 따라 달라집니다. POSIX 인증은 표준 인터페이스를 사용하여 소스 코드가 제공되는 애플리케이션의 관찰 가능한 동작을 테스트합니다. 내부 세부 정보는 다를 수 있으며, 이는 예제에 설명된 대로 strace/ltrace가 표시하는 내용입니다 exit_group.

추가 자료:

관련 정보