您在这里看到的是动态加载器打开并读取所需库的头文件。几乎所有 ELF 程序(这是 Linux 中的标准可执行格式)的 strace 都以大量的 open/read/mmap/close 开始,因为动态加载器正在加载所需库。
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\20\273\0\0\0\0\0\0"..., 832) = 832
加载器正在从文件中读取的内容:
3
: 这是通过 open()
打开文件后分配给文件的文件描述符 fd
。
"\177ELF\2\1\1\0..."
: 这是被读取的文件内容。数字是八进制转义序列,例如\1
表示字节1。它们以这种方式输出,因为否则您将无法看到它们,并且会在终端上创建混乱,因为大多数这些字符都是特殊的不可打印字符。
832
: 这是加载器要从文件中读取的字节数。
= 832
: 这是 read()
的结果,表示已经读取了所有请求的字节。
换句话说,这些转义序列只是使不可打印的字节可读。您可以使用 od -bc
命令对加载器尝试打开的文件运行测试,以八进制形式查看其内容以及可打印字符和反斜杠转义:
$ od -bc /lib/x86_64-linux-gnu/libc.so.6 | head -n4
0000000 177 105 114 106 002 001 001 003 000 000 000 000 000 000 000 000
177 E L F 002 001 001 003 \0 \0 \0 \0 \0 \0 \0 \0
0000020 003 000 076 000 001 000 000 000 260 034 002 000 000 000 000 000
003 \0 > \0 001 \0 \0 \0 260 034 002 \0 \0 \0 \0 \0
以下是更完整的示例,来自
strace /bin/true
:
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 4
read(4, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\4\2\0\0\0\0\0"..., 832) = 832
fstat(4, {st_mode=S_IFREG|0755, st_size=1689360, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f0d3d877000
mmap(NULL, 3795296, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 4, 0) = 0x7f0d3d2dd000
mprotect(0x7f0d3d472000, 2097152, PROT_NONE) = 0
mmap(0x7f0d3d672000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 4, 0x195000) = 0x7f0d3d672000
mmap(0x7f0d3d678000, 14688, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f0d3d678000
close(4)
您可以看到加载程序正在打开“libc”,这是标准C库的ELF文件。它读取其头文件以确定要加载哪些部分,然后将所有所需的部分映射到内存中,并分配正确的权限。
man strace
中发现"字符指针被解引用为C字符串",这是我现在通过搜索read
所能找到的所有信息。请问您是否可以发布一个链接/指针,让我可以进一步了解此问题? - Marisha