4

strace pwd

getcwd("/root"..., 4096)                = 6

ltrace pwd

getcwd(NULL, 0)                                     = "/root"

为什么第一个参数NULLltrace

似乎 strace/ltrace 都使用ptrace系统调用,但为什么它们得到不同的信息?

4

3 回答 3

4

是的,他们都使用ptrace,而且他们得到不同的信息。这是因为它们的使用ptrace方式不同。

如果您查看ptrace 手册页,您会发现存在几个决定 ptrace 行为的“请求”值。

更具体地说,如果您ptrace以前设置了 option PTRACE_O_TRACESYSGOOD,则可以区分导致系统调用的陷阱和不导致系统调用的陷阱。

于 2012-11-10T18:29:35.507 回答
3

ltrace显示库调用。在这种情况下,它显示了libc源代码正在调用的函数。

如果您看到pwd's source,您将看到(coreutils-8.13,文件 lib/xgetcwd.c):

char *cwd = getcwd (NULL, 0);

所以,ltrace的输出是正确的:pwd执行getcwd(NULL, 0)。根据 Linux 手册页getcwd(3)

如果 buf 为 NULL,getcwd() 使用 malloc(3) 动态分配缓冲区。

然而,系统调用getcwd(2)总是需要一个不同于 NULL 的第一个参数来复制路径名。您可以在 libc 源代码中看到这是如何完成的(例如,libc-3.13,文件 sysdeps/unix/sysv/linux/getcwd.c)。

库调用getcwd(NULL, 0)执行系统调用getcwd(path, alloc_size),其中path是先前 malloc() 的结果,alloc_size是页面大小 (4096)。

为了确认这一点,如果您运行,ltrace -S pwd您将看到库调用和系统调用:您将看到如下内容:

getcwd(NULL, 0 <unfinished ...>
SYS_getcwd("/root", 4096)                        = 6
<... getcwd resumed> )                           = "/root"
于 2014-08-13T12:26:11.780 回答
2

因为系统调用和库调用不同。阅读 getcwd 函数的手册页,您会看到它具有以下原型:

long getcwd(char *buf, unsigned long size);
于 2011-06-23T12:28:40.107 回答