除了我正在运行execl(“/ bin / ls”,“ls”,NULL);它与this one相同.
[user@ test]# ./test_trace
syscall 59 called with rdi(0),rsi(0),rdx(0)
syscall 12 returned with -38
syscall 12 called with rdi(0),rdx(140737288485480)
syscall 9 returned with -38
syscall 9 called with rdi(0),rsi(4096),rdx(3)
syscall 9 returned with -38
syscall 9 called with rdi(0),rdx(3)
syscall 21 returned with -38
syscall 21 called with rdi(233257948048),rsi(4),rdx(233257828696)
...
谁知道原因?
UPDATE
现在的问题是:
execve called with rdi(4203214),rsi(140733315680464),rdx(140733315681192)
execve returned with 0
execve returned with 0
...
execve两次返回0,为什么?
正如ptrace(2)
man page所述:
PTRACE_TRACEME
Indicates that this process is to be traced by its parent. Any signal (except SIGKILL) delivered to this process will cause it to stop and its parent to be notified via wait(). Also,all subsequent calls to exec() by this process will cause a SIGTRAP to be sent to it,giving the parent a chance to gain control before the new program begins execution. […]
你说你运行的原始代码“与this one相同,只是我正在运行execl(”/ bin / ls“,”ls“,NULL);”.好吧,它显然不是,因为你正在使用x86_64而不是32位并至少更改了消息.
但是,假设你没有改变太多其他的东西,第一次wait()唤醒了父级,它不是用于系统调用进入或退出 – 父级还没有执行ptrace(PTRACE_SYSCALL,…).相反,你看到这个通知孩子已经执行了一个exec(在x86_64上,系统调用59是execve).
代码错误地将其解释为syscall条目.然后它调用ptrace(PTRACE_SYSCALL,…),并在下次唤醒父进程时使用syscall条目(syscall 12),但代码将其报告为syscall exit.
请注意,在这个原始情况下,您永远不会看到execve系统调用进入/退出 – 只有附加通知 – 因为父级在它发生之前不会执行ptrace(PTRACE_SYSCALL,…).
如果您确实安排了代码以便捕获execve系统调用进入/退出,您将看到您观察到的新行为.父语句将被唤醒三次:一次用于execve系统调用条目(由于使用了ptrace(PTRACE_SYSCALL,一次用于执行系统调用退出(也是由于使用了ptrace(PTRACE_SYSCALL,…))和第三次执行exec通知的时间(无论如何都会发生).
这是一个完整的示例(对于x86或x86_64),它通过首先停止子进程来注意显示exec本身的行为:
#include
dio.h> #include 给出这样的东西(这是64位的 – 系统调用号对于32位是不同的;特别是execve是11,而不是59):
Child stopped due to signal 19 SIGTRAP: syscall 59,rc = -38 SIGTRAP: syscall 59,rc = 0 SIGTRAP: syscall 59,rc = 0 SIGTRAP: syscall 63,rc = -38 SIGTRAP: syscall 63,rc = 0 SIGTRAP: syscall 12,rc = -38 SIGTRAP: syscall 12,rc = 5324800 ...信号19是显式SIGSTOP;如上所述,孩子为执行者停了三次;然后两次(进入和退出)进行其他系统调用.
如果你对ptrace()的所有细节都非常有趣,那么我所知道的最好的文档是
README-linux-ptrace
源文件中的README-linux-ptrace
文件.正如它所说,“API很复杂并且有微妙的怪癖”……