为什么_do_fork()的kretprobe只返回一次?
作者:互联网
当我用fork编写一个小脚本时,syscall返回两次进程(每个进程一次):
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
int pid = fork();
if (pid == 0) {
// child
} else if (pid > 0) {
// parent
}
}
如果我使用systemtap进行检测,则只会发现一个返回值:
// fork() in libc calls clone on Linux
probe syscall.clone.return {
printf("Return from clone\n")
}
(SystemTap installes probes on _do_fork
而不是克隆,但这不应更改任何内容.)
这使我感到困惑.几个相关的问题:
>为什么系统调用仅返回一次?
>如果我正确理解_do_fork
code,则该过程将克隆到该函数的中间. (copy_process和wake_up_new_task).后续代码不应该同时在两个进程中运行吗?
>系统调用之后的内核代码是否与系统调用之前的用户代码在同一线程/进程中运行?
解决方法:
>创建孩子可能失败,因此必须检测并处理错误
>孩子的返回值不同,这也必须处理
>可能是家长有清理工作/需要执行的其他操作
因此,代码将不得不区分以父级和子级执行.但是没有排序检查,这已经很明显地暗示了孩子首先不会执行此代码.因此,人们应该寻找一个专门的地方,让新的孩子们返回.
由于代码很大而且很繁琐,因此可以尝试作弊,仅在特定于弓的代码中查找“ fork”,这很快就会显示ret_from_fork.
通过->设置起点. do_fork-> copy_process-> copy_thread_tls http://lxr.free-electrons.com/source/arch/x86/kernel/process_64.c#L158
从而
Why does the syscall only return once?
它不会返回一次.有2个返回线程,除了另一个使用不同的代码路径.由于探针仅安装在第一个探针上,因此看不到另一个探针.另请参阅下文.
If I understand the _do_fork code correctly, the process is cloned in the middle of the function. (copy_process and wake_up_new_task). Shouldn’t the subsequent code run in both processes?
我之前提到这是错误的.真正的问题是,让孩子返回与父母同一个地方有什么好处?我看不到任何东西,而且会很麻烦(如上所述,需要额外的特殊大小写).重申一下:让孩子返回其他地方,使呼叫者不必处理返回的孩子.他们只需要检查错误.
Does the kernel code after a syscall run in the same thread / process as the user code before the syscall?
什么是“系统调用后的内核代码”?如果您是线程X并进入内核,那么您仍然是线程X.
标签:kernel,systemtap,kprobe,c-3,linux 来源: https://codeday.me/bug/20191026/1933810.html