开发者

strace/ltrace outputs inconsistent info

开发者 https://www.devze.com 2023-03-15 08:51 出处:网络
strace pwd: getcwd("/root"..., 4096)= 6 ltrace pwd: getcwd(NULL, 0)= "/root" Why the 1st parameter is NULL in ltrace?

strace pwd:

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

ltrace pwd:

getcwd(NULL, 0)                                     = "/root"

Why the 1st parameter is NULL in ltrace?

It eems strace/ltrace both uses the ptrace syscall,but why 开发者_如何学运维they get different info?


Right, they both use ptrace, and also they get different info. This is because they use ptrace differently.

If you have a look at the ptrace man page, you will see that there exist several 'request' values, which decide the behaviour of ptrace.

More concretely, if you use ptrace to previously set the option PTRACE_O_TRACESYSGOOD, you have a way to distinguish between the traps leading to system calls and the traps that are not leading to system calls.


ltrace shows the library call. In this case, it shows the function from the libc that the source code is calling.

If you see pwd's source, you will see (coreutils-8.13, file lib/xgetcwd.c):

char *cwd = getcwd (NULL, 0);

So, ltrace's output is correct: pwd executes getcwd(NULL, 0). According to the Linux man page getcwd(3):

getcwd() allocates the buffer dynamically using malloc(3) if buf is NULL.

However, the system call getcwd(2) always needs a first argument different from NULL, to copy there the pathname. You can see how this is done in the libc source (eglibc-3.13, file sysdeps/unix/sysv/linux/getcwd.c).

The library call getcwd(NULL, 0) executes the system call getcwd(path, alloc_size), where path is the result of a previous malloc(), and alloc_size is the page size (4096).

To confirm this, if you run ltrace -S pwd you will see both the library calls and the system calls: you will see something like:

getcwd(NULL, 0 <unfinished ...>
SYS_getcwd("/root", 4096)                        = 6
<... getcwd resumed> )                           = "/root"


Because the system call and the library call are different. Read the manpage for the getcwd function and you'll see that it has the following prototype:

long getcwd(char *buf, unsigned long size);
0

精彩评论

暂无评论...
验证码 换一张
取 消