c - Linux 读取 strace 记录的系统调用 - 如何理解指向缓冲区值的指针?

标签 c pointers file-descriptor strace

我运行了 strace 并在它的输出中得到如下行:

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

我在 read 上读过 man ,所以字符串 "" 是指向 buf (ssize_t read(int fd, void *buf, size_t count);) 的指针,但是那个特定的字符串是什么意思?特别是:

  • ELF 最有可能是可执行链接的 - 为什么这里是指针?
  • \ 让特殊字符转义 - 为什么在这里转义数字?
  • > 是做什么用的?

最佳答案

您在这里看到的是动态加载程序打开并读取所需库的 header 。 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文件。它读取其 header 以确定要加载的部分,然后mmap内存中所有需要的部分,分配正确的权限。

关于c - Linux 读取 strace 记录的系统调用 - 如何理解指向缓冲区值的指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58049023/

相关文章:

C++ 套接字问题

c - fgets 会更改文件描述符集吗?

c++ - 重写代码: Output from file to char* ~> is FILE* to virtual file in RAM possible?

连接两个字符串,中间为空

c - 读取数字序列并显示消息的 C 程序

c - 解释一下输出。它正在打印每个字母表的下一个字母表

c - 尝试将结构体中的指针分配给二维数组

反问题(C程序)

c - Linux:如何检查是否创建了新进程

c++ - 指针数据变化