strace如何在跟踪过程中从失败的系统调用中获取errno?
例如,如果我执行strace ls
,则strace在呼叫失败时显示符号errno值(例如ENOENT
)。我知道strace在后台使用ptrace。
如果我使用ptrace跟踪系统调用的进程,如何在跟踪的进程中读取errno的值?
更具体地说,如何在子进程中获取errno的地址,以便可以使用PTRACE_PEEKDATA
或process_vm_readv
读取它?
谢谢
在系统调用之后,您需要获取寄存器,特别是rax
。如果系统调用失败,则rax
的值将是一个较高的数字,例如0xFFFFFFFFFFFFFFFC
。通过像这样否定此数字来计算errno
:
-0xFFFFFFFFFFFFFFFC = 0xFFFFFFFFFFFFFFFF - 0xFFFFFFFFFFFFFFFC + 1 = 0xD = 13
一旦有了errno
,就可以在errno.h
中进行查找。在不同的系统上,位置有所不同。如果找不到它,可以运行echo "#include <errno.h>" | gcc -E -
,它将打印出位置。在此示例中,错误为EACCES
,也就是“权限被拒绝”。