Strace Hello World 程序

Strace Hello World 程序

所以我试图用下面的“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说明,上证2),并寻找可以使用这些额外功能来更有效运行的库二进制版本;当它无法找到可以使用所有功能的功能时,它会寻找更通用的功能。最后,在标准系统目录中找到了该库的非专用版本。

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)                           = ?

这是您的程序退出,其中包括刷新标准输出缓冲区。

相关内容