为什么这个ptrace程序说syscall返回-38?

前端之家收集整理的这篇文章主要介绍了为什么这个ptrace程序说syscall返回-38?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

除了我正在运行execl(“/ bin / ls”,“ls”,NULL);它与this one相同.

结果显然是错误的,因为每个系统调用都返回-38:

[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,为什么?

最佳答案
代码不考虑来自子进程的exec的通知,因此最终将syscall条目作为syscall exit处理,并且syscall exit作为syscall条目.这就是为什么你在“syscall 12调用”等之前看到“syscall 12返回”的原因(-38是ENOSYS,它是由内核的系统调用条目代码作为默认返回值放入RAX中的.)

正如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很复杂并且有微妙的怪癖”……

猜你在找的Linux相关文章