strace / ltrace выводит противоречивую информацию - PullRequest
4 голосов
/ 23 июня 2011

strace pwd:

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

ltrace pwd:

getcwd(NULL, 0)                                     = "/root"

Почему первый параметр равен NULL в ltrace?

UPDATE

кажется, что strace / ltrace оба используют системный вызов ptrace, но почему они получают разную информацию?

Ответы [ 3 ]

4 голосов
/ 10 ноября 2012

Да, они оба используют ptrace, а также они получают различную информацию.Это потому, что они используют ptrace по-разному.

Если вы загляните на справочную страницу ptrace , вы увидите, что существует несколько значений 'request', которые определяют поведениеptrace.

Более конкретно, если вы используете ptrace для предварительной установки опции PTRACE_O_TRACESYSGOOD, у вас есть способ различать ловушки, ведущие к системным вызовам, и ловушки, которые не ведут к системным вызовам.

3 голосов
/ 13 августа 2014

ltrace показывает вызов библиотеки.В этом случае он показывает функцию из libc, которую вызывает исходный код.

Если вы видите исходный код pwd, вы увидите (coreutils-8.13, файл lib / xgetcwd.c):

char *cwd = getcwd (NULL, 0);

Итак, вывод ltrace правильный: pwd выполняет getcwd(NULL, 0).Согласно справочной странице Linux getcwd(3):

getcwd () динамически распределяет буфер с помощью malloc (3), если buf равен NULL.

Однако системный вызовgetcwd(2) всегда нужен первый аргумент, отличный от NULL, чтобы скопировать туда путь.Вы можете увидеть, как это делается в исходном коде libc (eglibc-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"
2 голосов
/ 23 июня 2011

Поскольку системный вызов и вызов библиотеки различаются.Прочтите man-страницу для функции getcwd, и вы увидите, что она имеет следующий прототип:

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