4

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?

TylerH
  • 20,799
  • 66
  • 75
  • 101
Je Rog
  • 5,675
  • 8
  • 39
  • 47

3 Answers3

4

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.

Dave Clemmer
  • 3,741
  • 12
  • 49
  • 72
kosklain
  • 399
  • 3
  • 17
3

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"
Juan Cespedes
  • 1,299
  • 12
  • 27
2

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);
zvrba
  • 24,186
  • 3
  • 55
  • 65
  • 1
    @zvrba,why do you think this answers my question? – Je Rog Jun 23 '11 at 13:37
  • Because the manpage also explains that passing NULL is a linux extension. And it might also be a bug in ltrace. Impossible to know w/o seeing the code. – zvrba Jun 23 '11 at 14:05
  • 1
    ptrace() knows absolutely nothing about parameters. function/syscall arguments and how they should be interpreted are hard-coded into strace and ltrace. – zvrba Jun 23 '11 at 14:08
  • @zvrba ,what's the most important bit of code control that makes strace/ltrace have different feature? – Je Rog Jun 27 '11 at 11:57
  • I don't understand what you're asking there. Which feature? strace hooks into the system call mechanism, ltrace modifies entry points of dynamic library functions. – zvrba Jun 27 '11 at 12:51
  • @zvrba,can you explain brieftly how it's done with `ptrace`,say , `hooks into the system call mechanism` and `modifies entry points of dynamic library functions`? – Je Rog Jun 28 '11 at 11:20
  • It cannot be explained "briefly". Read the ptrace manpage, ELF documentation, Linux ABI documentation and the source for strace and ltrace. – zvrba Jun 29 '11 at 07:41