Ptrace прочитал errno значение в дочернем процессе - PullRequest
4 голосов
/ 11 марта 2020

Как strace получает ошибку из-за сбоя системных вызовов в процессе, который она отслеживает?

Например, если я делаю strace ls, strace отображает значение символа c errno (например, ENOENT), когда вызов не удался. Я знаю, что Strace использует ptrace под капотом.

Если я использую ptrace для отслеживания системных вызовов процессов, как я могу прочитать значение errno в отслеживаемом процессе?

Более конкретно, как мне получить адрес errno в дочернем процессе, чтобы я мог прочитать его, используя PTRACE_PEEKDATA или process_vm_readv?

Спасибо

1 Ответ

1 голос
/ 04 мая 2020

После системного вызова вам нужно получить регистры, в частности rax. Если системный вызов не удался, тогда значение для rax будет большим числом, таким как 0xFFFFFFFFFFFFFFFC. errno рассчитывается путем отрицания этого числа следующим образом:

-0xFFFFFFFFFFFFFFFC = 0xFFFFFFFFFFFFFFFC - 0xFFFFFFFFFFFFFFFC + 1 = 0xD = 13

Когда у вас есть errno, вы можете посмотреть его в errno.h. Расположение немного отличается в разных системах; если у вас возникли проблемы с его поиском, вы можете запустить echo "#include <errno.h>" | gcc -E -, который распечатает местоположение. В этом примере ошибка EACCES, она же «Отказано в доступе».

...