如何实现一个系统调用,它可以在不进入内核日志的情况下检查自身是不是已成功执行?

Posted

技术标签:

【中文标题】如何实现一个系统调用,它可以在不进入内核日志的情况下检查自身是不是已成功执行?【英文标题】:How to implement a system call that could check if itself has been successfully executed without going to the kernel log?如何实现一个系统调用,它可以在不进入内核日志的情况下检查自身是否已成功执行? 【发布时间】:2021-04-19 01:58:20 【问题描述】:

我刚刚进入内核世界,想添加一些系统调用。我的目标是添加一个系统调用,让我检查它是否执行(不查看内核日志)。不过,我想了很久,还没想好怎么实现。谁能给我一些建议?还是一些伪代码?提前致谢。

我的想法是我们可以实现一个新的系统调用,它将一些东西写入缓冲区。然后,另一个系统调用读取缓冲区的内容以检查先前的系统调用是否已写入缓冲区。 (有点像 pthread_createpthread_join)因此,我的实现总共包含 2 个系统调用。

这是我用伪代码写的想法草图:

syscall_2(...)
    if (syscall_1 executes)
        return 0;
    if (syscall_1 NOT executes)
        return -1;


syscall_1()
    do something;
    create a buffer;
    write something into buffer;
    
    return syscall_2(buffer); // checks what is in buffer

【问题讨论】:

为什么等待系统调用完成会出现问题?比如,你最终想在这里完成什么? 另外,听起来您可能想在问题中概述您要解决的实际问题。 我的目标是添加一个系统调用,让我检查它是否执行(不查看内核日志)。 @Omnifarious 感谢您的建议,我会编辑问题。 @oakad 系统调用全部返回错误码。您可以通过检查错误代码轻松判断系统调用是否完成。为什么需要另一种方法来发现系统调用是否成功完成?你想达到什么目的。你想解决什么问题,你认为你需要这样做才能解决它? 【参考方案1】:

我的建议是让系统调用本身接受指向用户空间缓冲区的指针,并用特定信息覆盖该缓冲区。

您将必须学习如何访问用户空间内存,更重要的是如何验证您是否获得了指向该进程已映射的内存的指针,并且具有写入权限。

然后,一旦系统调用完成,调用它的程序不仅可以检查系统调用的返回码,还可以检查内存以查看系统调用是否写入了正确的内容。

【讨论】:

谢谢!这是很好的解释。【参考方案2】:

通常,系统调用会通知调用者它们是否被执行(它是如何执行的),所以我猜您想知道哪些系统调用已被执行,以及执行了多少次。

从这个角度来看,我认为最好的方法是实现一个可查询的设备(通过一些 ioctl 调用),并让您了解您可能感兴趣的各个系统调用的统计信息。

例如....您可以实现您在一段时间内使用的n类型的系统调用的数量...通过在间隔开始时间和结束时间检查计数器,然后检查有多少调用(如果您实现了一个计数器),您只需在两次都减去计数器值。你也可以对例如做同样的事情。通过累积系统调用在结束时执行的时间来计算平均时间。例如,如果您以皮秒为单位执行此操作,则可以确定这是一个可以发布的好主意。在此模式中,您还可以通过计算传入/传出用户模式的字节数来计算每个系统调用执行的 I/O 量...。您可以将其作为 ioctls 实现到某些设备,然后您不需要需要为其添加系统调用。

【讨论】:

以上是关于如何实现一个系统调用,它可以在不进入内核日志的情况下检查自身是不是已成功执行?的主要内容,如果未能解决你的问题,请参考以下文章

Linux内核与内核函数与操作系统,系统调用,这几者的联系是什么?

Linux - 系统日志客户端

用户空间实现线程 内核实现线程 线程的调度

linux系统中,进程进行系统调用进入内核态时,是该进程本身进入内核态还是操作系统新开了一个内核线程?

如何在不通过 Web 调用的情况下在浏览器中查找地理位置

是否可以在不使用malloc的情况下进行内存泄漏?