附加到进程后,如何检查示踪是否在系统调用中?

时间:2018-08-28 11:06:34

标签: c linux ptrace

根据the ptrace manual page

  

Syscall-enter-stop和syscall-exit-stop与   示踪剂相互之间。跟踪器需要跟踪   为了不误解syscall-enter-,ptrace-stops的顺序   停止为syscall-exit-stop,反之亦然。

当我使用PTRACE_ATTACH附加到进程时,如何知道该示踪当前是否在syscall中?换句话说,如果我使用PTRACE_SYSCALL重新启动跟踪,如何知道下一个系统调用停止是syscall-enter-stop还是syscall-exit-stop

3 个答案:

答案 0 :(得分:0)

  

当我使用PTRACE_ATTACH附加到进程时,如何知道该示踪当前是否在系统调用中?

当您使用PTRACE_ATTACH附加到进程时,将向tracee发送一个STOP信号。

执行用户空间代码,进入系统调用,阻塞内核中的“慢”系统调用以及从系统调用返回用户空间时,STOP信号都可以生效。

通过检查指令指针和指令指针周围的指令,通常可以确定进程是否在执行用户空间代码,但仅此而已。

但是,由于停止点本质上是随机的,因此您可以等待进程停止,然后使用PTRACE_SINGLESTEP单步执行其每个线程,直到指令指针更改为止。然后,您知道线程正在执行用户空间代码。

或者,如果单步操作导致线程长时间阻塞,则意味着线程正在执行阻塞的慢速系统调用。

  

换句话说,如果我使用PTRACE_SYSCALL重新启动跟踪,如何知道下一个syscall-stop是syscall-enter-stop还是syscall-exit-stop?

您不知道,除非您知道追迹停止的状态。如前所述,您可以通过单步执行代码直到指令指针更改来实现。

答案 1 :(得分:0)

当跟踪的过程在系统调用ENTRY上停止时,EAX寄存器将包含-ENOSYS,并且orig_rax具有该系统调用的编号。

下面的代码示例演示了一个示例。

if (registers.rax == -ENOSYS)
                { switch (registers.orig_rax)
                        {
                          case _NR_open: //Example
                          break;
                          default:
                    // to get the arguments

                        fprintf(stderr, "%#08x, %#08x, %#08x",
                                registers.rbx, registers.rcx, 
                                                registers.rdx);
                     break;
                     }
              }
              else
              {
                if (registers.rax < 0)
                {
                        // error condition
                        fprintf(stderr, "#Err: %s\n", 
                 errors[abs(registers.rax)]);
                }
                else
                {
                        // return code
                        fprintf(stderr, "%#08x\n", registers.rax);
                }
        }

答案 2 :(得分:-1)

我不相信您可以使用ptrace来做到这一点。 ptrace traces 毕竟是它显示事件,并且无法检查历史记录(它没有要跟踪的进程堆栈的概念)。

但是,然后,您可以使用gdb以相同的方式附加到正在运行的进程。

$ gdb -p 20334
...
Attaching to process 20334
...
> bt

这将为您提供该过程的堆栈跟踪。如果您已安装内核的调试符号,则可以看到内核功能列表(而不只是“ ???”)。