PTRACE_GET_SYSCALL_INFO 总是 returns info.op 作为 "PTRACE_SYSCALL_INFO_NONE"

PTRACE_GET_SYSCALL_INFO always returns info.op as "PTRACE_SYSCALL_INFO_NONE"

基本上是标题,我无法让它工作,也找不到任何它不应该工作的原因。

ptrace(2)'s manual states that Linux 5.3+ is required and i am 运行 Linux 5.17.4,以下简化代码编译时没有任何警告,在检测每个系统调用时运行时没有任何错误,但 syscall_info.op 始终具有值 PTRACE_SYSCALL_INFO_NONE.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <signal.h>
#include <unistd.h>
#include <sys/user.h>

#include <syscall.h>
#include <sys/ptrace.h>
#include <linux/ptrace.h>

#include <sys/errno.h>

int main(int argc, char **argv) {
    pid_t pid = fork();

    switch(pid) {
        case -1:
            //error...
        case 0:
            ptrace(PTRACE_TRACEME, 0, NULL, NULL);
            execvp(argv[1], argv + 1);
            //error...
    }

    waitpid(pid, NULL, 0);
    ptrace(PTRACE_SETOPTIONS, pid, NULL, PTRACE_O_EXITKILL);

    struct ptrace_syscall_info syscall_info;
    size_t size = sizeof(syscall_info);
    while(1) {
        if(ptrace(PTRACE_SYSCALL, pid, NULL, NULL) == -1) {
            //error...
        }
        if(waitpid(pid, NULL, 0) == -1) {
            //error...
        }
        
        // syscall entry
        if(ptrace(PTRACE_GET_SYSCALL_INFO, pid, (void *)size, &syscall_info) == -1) {
            //error...
        }

        /* syscall_info.op is always PTRACE_SYSCALL_INFO_NONE
           instead of PTRACE_SYSCALL_INFO_ENTRY */

        if(ptrace(PTRACE_SYSCALL, pid, NULL, NULL) == -1) {
            //error...
        }
        if(waitpid(pid, NULL, 0) == -1) {
            //error...
        }

        // syscall exit
        if(ptrace(PTRACE_GET_SYSCALL_INFO, pid, (void *)size, &syscall_info) == -1) {
            if(errno == ESRCH) {
                exit(syscall_info.exit.rval);
            }
            //error...
        }

        /* Same here, should be PTRACE_SYSCALL_INFO_EXIT but still
           is PTRACE_SYSCALL_INFO_NONE */
    }
}

过去 3 天一直在谷歌搜索,但我找不到太多可以验证我是否正确使用它的信息,也没有找到任何解释为什么这不起作用的帖子。我甚至研究了 strace 的源代码以了解他们是如何做到的,我所能找到的只是几个宏来测试是否首先支持 PTRACE_GET_SYSCALL_INFO但不知道这些测试是什么。如果 PTRACE_GET_SYSCALL_INFO 除了内核版本之外还有某些标准,为什么手册中没有列出它们?

经过一些挖掘,您似乎必须启用 PTRACE_SETOPTIONSPTRACE_O_TRACESYSGOOD 选项才能从 PTRACE_GET_SYSCALL_INFO 获得完整信息。

似乎没有记录此要求。不清楚是有意为之还是内核错误。