ios - fork() 通过使用 svc 调用实现

标签 ios c fork inline-assembly

我实现了系统调用宏来调用软件中断调用。它对许多系统调用都运行良好。但是,它不适用于 fork()。父进程和子进程的返回 pid 相同。片段如下:

#define SYSCALL0(N) ({                                          \
    register int ip asm("ip") = N;                              \
    register int r0 asm("r0");                                  \
    asm volatile("swi 0x80" : "=r"(r0) : "r"(ip) : "memory");   \
    r0;                                                         \
})

int main(int argc, char * argv[]) {
   NSLog(@"--beginning of program\n");
    int counter = 0;
    pid_t pid = SYSCALL0(2);
    if (pid == 0) {
        NSLog(@"pid = %d", getpid());
        // child process
        for (int i = 0; i < 3; ++i)
            NSLog(@"child process: counter=%d\n", ++counter);
    }
    else if (pid > 0)  {
        NSLog(@"pid = %d", getpid());
        // parent process
        for (int i = 0; i < 3; ++i)
            NSLog(@"parent process: counter=%d\n", ++counter);
    }
    else {
        // fork failed
        NSLog(@"fork() failed!\n");
        return 1;
    }
    NSLog(@"--end of program--\n");
}

输出:

2015-10-11 21:29:43.666 Training[2564:907] --beginning of program
2015-10-11 21:29:43.669 Training[2564:907] pid = 2650
2015-10-11 21:29:43.670 Training[2564:907] parent process: counter=1
2015-10-11 21:29:43.670 Training[2564:907] parent process: counter=2
2015-10-11 21:29:43.669 Training[2564:907] pid = 2650
2015-10-11 21:29:43.671 Training[2564:907] parent process: counter=3
2015-10-11 21:29:43.671 Training[2564:907] --end of program--
2015-10-11 21:29:43.671 Training[2564:907] parent process: counter=1
2015-10-11 21:29:43.672 Training[2564:907] parent process: counter=2
2015-10-11 21:29:43.673 Training[2564:907] parent process: counter=3
2015-10-11 21:29:43.674 Training[2564:907] --end of program--

测试环境是在armv7上运行的越狱iOS(非越狱不会运行)。 我想我可能对 swi 调用的返回做得不够,所以它不能返回 0 来指示子进程。我错过了什么?如何让它正常工作?

最佳答案

你不能那样做系统调用。正如您刚刚注意到的,系统调用的用户空间包装器所做的工作远不止于此。因此,要么找到适用于您的操作系统的源代码,弄清楚系统调用是如何包装的并执行相同的操作,要么只使用为您提供的方便的包装器。

我很确定 iOS 仍然以 BSD 方式进行系统调用。我碰巧知道fork使用了两个返回值系统调用接口(interface),一个寄存器包含进程是否为子进程,另一个寄存器包含返回值。

此外,您的包装器可能没有正确处理错误(这通常通过您必须专门处理的标志发出信号)。并且至少一些操作系统(不知道 iOS 是否是其中之一)确切地知道哪些寄存器保存在系统调用包装器中并且不会费心去保存它们,所以像这样内联系统调用可能会破坏你的寄存器。

关于ios - fork() 通过使用 svc 调用实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32985409/

相关文章:

iOS 4 : video quality with AVAsset based application

ios - UICollectionViewCell 中的按钮点击也会切换另一个单元格中的状态

ios - 交货时是否可以获得远程推送通知的交货收据?

c - printf 如何在 CUDA 计算上工作 >= 2

c - 父进程正在向子进程发出信号,但子进程的信号处理需要改进

iPhone - UIScrollView ...检测触摸坐标

在 Mac 上的 Xcode 中使用 fopen(fileName, "wb") 后无法访问我的二进制文件

c - skb->data_len 、 skb->len 、 skb->mac_len 的值为 0 是否正确?

linux - fork() 炸弹的进程​​解释?

c - 来自 fork() 的 pid 永远不会传给 parent ,唯一的 child