그래서 저는 다음과 같은 "Hello World!" 시스템콜을 이해하려고 노력하고 있습니다. 프로그램:
#include <stdio.h>
int main(){
printf("Hello World!\n");
return 0;
}
그런 다음 실행 파일에서 strace를 실행하면 다음을 얻습니다.
execve("./hello", ["./hello"], [/* 62 vars */]) = 0
brk(0) = 0x85a5000
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb774f000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/home/miguel/GNUstep/Library/Libraries/tls/i686/sse2/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/home/miguel/GNUstep/Library/Libraries/tls/i686/sse2", 0xbf8df160) = -1 ENOENT (No such file or directory)
open("/home/miguel/GNUstep/Library/Libraries/tls/i686/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/home/miguel/GNUstep/Library/Libraries/tls/i686", 0xbf8df160) = -1 ENOENT (No such file or directory)
open("/home/miguel/GNUstep/Library/Libraries/tls/sse2/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/home/miguel/GNUstep/Library/Libraries/tls/sse2", 0xbf8df160) = -1 ENOENT (No such file or directory)
open("/home/miguel/GNUstep/Library/Libraries/tls/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/home/miguel/GNUstep/Library/Libraries/tls", 0xbf8df160) = -1 ENOENT (No such file or directory)
open("/home/miguel/GNUstep/Library/Libraries/i686/sse2/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/home/miguel/GNUstep/Library/Libraries/i686/sse2", 0xbf8df160) = -1 ENOENT (No such file or directory)
open("/home/miguel/GNUstep/Library/Libraries/i686/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/home/miguel/GNUstep/Library/Libraries/i686", 0xbf8df160) = -1 ENOENT (No such file or directory)
open("/home/miguel/GNUstep/Library/Libraries/sse2/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/home/miguel/GNUstep/Library/Libraries/sse2", 0xbf8df160) = -1 ENOENT (No such file or directory)
open("/home/miguel/GNUstep/Library/Libraries/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/home/miguel/GNUstep/Library/Libraries", 0xbf8df160) = -1 ENOENT (No such file or directory)
open("/usr/lib/tls/i686/sse2/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/tls/i686/sse2", 0xbf8df160) = -1 ENOENT (No such file or directory)
open("/usr/lib/tls/i686/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/tls/i686", 0xbf8df160) = -1 ENOENT (No such file or directory)
open("/usr/lib/tls/sse2/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/tls/sse2", 0xbf8df160) = -1 ENOENT (No such file or directory)
open("/usr/lib/tls/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/tls", 0xbf8df160) = -1 ENOENT (No such file or directory)
open("/usr/lib/i686/sse2/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/i686/sse2", 0xbf8df160) = -1 ENOENT (No such file or directory)
open("/usr/lib/i686/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/i686", 0xbf8df160) = -1 ENOENT (No such file or directory)
open("/usr/lib/sse2/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/sse2", 0xbf8df160) = -1 ENOENT (No such file or directory)
open("/usr/lib/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\1\1\1\3\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\300\177\1\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=2035943, ...}) = 0
mmap2(NULL, 1801892, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7573000
mmap2(0xb7724000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b0000) = 0xb7724000
mmap2(0xb7729000, 7844, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7729000
close(3) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7572000
set_thread_area({entry_number:-1, base_addr:0xb7572700, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0 (entry_number:6)
mprotect(0xb7724000, 12288, PROT_READ) = 0
mprotect(0xb7750000, 4096, PROT_READ) = 0
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7571000
write(1, "Hello World!\n", 13) = 13
exit_group(0) = ?
+++ exited with 0 +++
디스크에 없는 일부 라이브러리를 열려고 하는 시스템 호출이 많이 있습니다. 이 프로그램이 해당 파일에 액세스하려는 이유는 무엇입니까? 그런 일이 발생하는 것을 어떻게 방지할 수 있나요?
LD_LIBRARY_PATH 변수의 내용은 다음과 같습니다.
/home/miguel/GNUstep/Library/Libraries:/usr/lib
답변1
이것은 모두 완전히 정상입니다. 실패한 라이브러리 조회가 발생하는 것을 방지해서는 안 됩니다.
execve("./hello", ["./hello"], [/* 62 vars */]) = 0
이것이 프로그램 시작입니다. 동적으로 연결되어 있으므로 실행되는 첫 번째 코드는dynamic loader
.
brk(0) = 0x85a5000
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb774f000
동적 로더가 일부 힙 공간을 할당하고 있습니다.
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
동적 로더는 미리 로드할 동적 라이브러리가 있는지 확인합니다. 아무것도 없습니다.
open("/home/miguel/GNUstep/Library/Libraries/tls/i686/sse2/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/home/miguel/GNUstep/Library/Libraries/tls/i686/sse2", 0xbf8df160) = -1 ENOENT (No such file or directory)
open("/home/miguel/GNUstep/Library/Libraries/tls/i686/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/home/miguel/GNUstep/Library/Libraries/tls/i686", 0xbf8df160) = -1 ENOENT (No such file or directory)
open("/home/miguel/GNUstep/Library/Libraries/tls/sse2/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/home/miguel/GNUstep/Library/Libraries/tls/sse2", 0xbf8df160) = -1 ENOENT (No such file or directory)
open("/home/miguel/GNUstep/Library/Libraries/tls/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/home/miguel/GNUstep/Library/Libraries/tls", 0xbf8df160) = -1 ENOENT (No such file or directory)
open("/home/miguel/GNUstep/Library/Libraries/i686/sse2/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/home/miguel/GNUstep/Library/Libraries/i686/sse2", 0xbf8df160) = -1 ENOENT (No such file or directory)
open("/home/miguel/GNUstep/Library/Libraries/i686/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/home/miguel/GNUstep/Library/Libraries/i686", 0xbf8df160) = -1 ENOENT (No such file or directory)
open("/home/miguel/GNUstep/Library/Libraries/sse2/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/home/miguel/GNUstep/Library/Libraries/sse2", 0xbf8df160) = -1 ENOENT (No such file or directory)
open("/home/miguel/GNUstep/Library/Libraries/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/home/miguel/GNUstep/Library/Libraries", 0xbf8df160) = -1 ENOENT (No such file or directory)
open("/usr/lib/tls/i686/sse2/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/tls/i686/sse2", 0xbf8df160) = -1 ENOENT (No such file or directory)
open("/usr/lib/tls/i686/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/tls/i686", 0xbf8df160) = -1 ENOENT (No such file or directory)
open("/usr/lib/tls/sse2/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/tls/sse2", 0xbf8df160) = -1 ENOENT (No such file or directory)
open("/usr/lib/tls/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/tls", 0xbf8df160) = -1 ENOENT (No such file or directory)
open("/usr/lib/i686/sse2/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/i686/sse2", 0xbf8df160) = -1 ENOENT (No such file or directory)
open("/usr/lib/i686/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/i686", 0xbf8df160) = -1 ENOENT (No such file or directory)
open("/usr/lib/sse2/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/sse2", 0xbf8df160) = -1 ENOENT (No such file or directory)
open("/usr/lib/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
동적 로더는 libc6
표준 라이브러리인 를 찾고 있습니다. 여러 디렉터리에서 검색합니다. 먼저 에 지정된 디렉터리에서 찾은 LD_LIBRARY_PATH
다음 에 나열된 디렉터리에서 찾습니다 /etc/ld.so.conf
. (전체 내용은 매뉴얼을 참조하세요.) 각 디렉터리에서 로더는 먼저 여러 하위 디렉터리를 확인합니다. 즉, 어떤 하드웨어 기능이 있는지 확인합니다(P6 지침,SSE2), 이러한 추가 기능을 사용하여 보다 효율적으로 실행할 수 있는 라이브러리 바이너리 버전을 찾습니다. 모든 기능을 사용할 수 있는 기능을 찾지 못하면 보다 일반적인 기능을 찾습니다. 결국 라이브러리는 전문화되지 않은 버전의 표준 시스템 디렉토리에서 발견됩니다.
read(3, "\177ELF\1\1\1\3\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\300\177\1\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=2035943, ...}) = 0
mmap2(NULL, 1801892, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7573000
mmap2(0xb7724000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b0000) = 0xb7724000
mmap2(0xb7729000, 7844, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7729000
close(3) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7572000
set_thread_area({entry_number:-1, base_addr:0xb7572700, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0 (entry_number:6)
mprotect(0xb7724000, 12288, PROT_READ) = 0
mprotect(0xb7750000, 4096, PROT_READ) = 0
표준 라이브러리가 로드된 다음 초기화 코드가 실행됩니다.
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7571000
호출을 실행한 결과입니다 printf
.
write(1, "Hello World!\n", 13) = 13
exit_group(0) = ?
이는 stdout 버퍼 플러시를 포함하는 프로그램 종료입니다.