Ptrace прочитал значение ошибки в дочернем процессе

Как strace получает errno из неудачных системных вызовов в отслеживаемом процессе?

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

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

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

Спасибо


person NotAPro    schedule 11.03.2020    source источник
comment
errno — это концепция C (и при этом переменная для каждого потока), а не системная концепция. Значение, помещенное в errno, является отрицанием значения, возвращаемого системным вызовом. Вот почему это читается как RAX и почему это устанавливает RAX (при переопределении системного вызова).   -  person ikegami    schedule 12.03.2020
comment
Я вижу свою ошибку: вывод strace показывает, что системный вызов возвращает -1, но я предположил, что -1 также возвращается в rax, но это не так. Программа, которую я написал, также правильно показывает, что rax есть отрицание errno. Спасибо   -  person NotAPro    schedule 12.03.2020
comment
Не стесняйтесь опубликовать ответ. Я слишком устал, и у вас, видимо, есть рабочий код, которым вы могли бы поделиться :)   -  person ikegami    schedule 12.03.2020


Ответы (1)


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

-0xFFFFFFFFFFFFFFF4 = 0xFFFFFFFFFFFFFFFF - 0xFFFFFFFFFFFFFFF4 + 1 = 0xC = 12

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

person Will Da Silva    schedule 04.05.2020