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



我运行了strace,在其输出中,我得到了如下行:

read(3, "177ELF2113>120273"..., 832) = 832

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

  • ELF很可能是可执行文件链接的 - 为什么在这里使用指针?
  • 让我们转义特殊字符 - 为什么要在这里转义数字?
  • >它有什么用?

您在这里看到的是动态加载程序打开并读取所需库的标头。ELF 程序(这是 Linux 中的标准可执行格式(的几乎任何strace都以一堆open/read/mmap/close开头,原因如下:动态加载器正在加载所需的库。

您在这里看到的内容:

read(3, "177ELF2113>120273"..., 832) = 832

只是加载程序从文件中读取的内容:

  • 3:这是由open()分配给打开的文件的fd
  • "177ELF211...":这是正在读取的文件的内容。数字之所以存在,是因为它们是八进制转义序列,例如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                
0000020 003 000 076 000 001 000 000 000 260 034 002 000 000 000 000 000
003     >   001       260 034 002          

更完整的示例如下,来自strace /bin/true

open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 4
read(4, "177ELF21133>142"..., 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 文件。它读取其标头以确定要加载哪些部分,然后在内存中mmap所有需要的部分,分配正确的权限。

相关内容

  • 没有找到相关文章

最新更新