【问题标题】:what happens after a process calls ptrace(PTRACE_TRACEME, ...)?进程调用 ptrace(PTRACE_TRACEME, ...) 后会发生什么?
【发布时间】:2016-01-04 14:59:59
【问题描述】:

进程调用ptrace(PTRACE_TRACEME, ...)后,tracee停在哪里?

tracee 是否在exec() 系统调用中停止? (好像没有)

tracee 是否在动态链接器文本中停止?

...

如果我编译一个没有任何动态链接库和 glibc c-runtime 的可执行文件,并指定入口点, 被跟踪者将在入口点停止。

但是当我用 glibc(gcc hello-world.c) 编译一个可执行文件时,它会停在/lib/ld-2.20.so offset + 0xfb0。 (cat /proc/[pid]/maps)

希望有关此的更多详细信息。

man ptrace 似乎没有帮助。

【问题讨论】:

    标签: c linux gcc gdb


    【解决方案1】:

    当对execve() 的调用完成时,tracee 通常会停止,这将导致它被发送一个 SIGTRAP。
    有些使用raise() 来确保发送信号,如下所示:

    ptrace(PTRACE_TRACEME);
    kill(getpid(), SIGSTOP);
    return execvp(args[0], args);
    

    【讨论】:

    • 谢谢。那么,当tracee停止时,CPU EIP寄存器指向哪条指令呢?
    • 嗯,我会说它包含execve()系统调用号,但我完全不确定,所以你可以自己用gdb检查,有一个命令(info reg)这将显示您的进程寄存器的值!
    • 对不起我的模棱两可的陈述。当被跟踪对象停止时,CPU EIP 寄存器指向一条指令。这是什么指令?是属于glibc,动态链接器,还是其他?
    • 它可能是最后调用的来自 glibc C 的系统调用包装器(在这种情况下为 execve())
    • execve() 永远不会返回(如果没有错误),所以没有机会在包装器处停下来...... :(
    【解决方案2】:
    kill(getpid(), SIGSTOP);
    return execvp(args[0], args);
    

    谢谢。那么,当tracee停止时,CPU EIP寄存器指向哪条指令呢?

    kill(pid_t pid, int sig) 函数的规范回答了这个问题。

    如果 pid 的值导致为发送生成 sig 进程,如果 sig 没有被调用线程阻塞,如果没有 其他线程有 sig 未阻塞或正在等待 sigwait() 函数 对于 sig,应为 sig 或至少一个未决的未阻塞信号 在 kill() 返回之前传递给发送线程。

    因此,由于上述kill(getpid(), SIGSTOP),进程在库函数kill() 返回之前停止,通常是在系统调用之后的指令处。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-04-05
      • 1970-01-01
      • 1970-01-01
      • 2013-06-18
      • 2012-09-18
      • 1970-01-01
      • 2011-08-05
      相关资源
      最近更新 更多