Fork系统调用失败后,rax中的返回值是多少? [英] What is the return value in rax after a failed Fork syscall?

查看:182
本文介绍了Fork系统调用失败后,rax中的返回值是多少?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道在C中调用fork()会在出现错误时返回-1,但是我想知道在汇编中调用sys_fork时错误返回值是什么.

I know that calling fork() in C will return -1 if there is an error, but I'm wondering what the error return value is when you call sys_fork in assembly.

我通常可以假设它也返回-1,但是我已经处理过sys_brk,而汇编中的原始syscall返回的内容与C Brk()包装器有所不同.

I might normally assume that it also returns -1 but I've dealt with sys_brk and the raw syscall in assembly returns something different from the C Brk() wrapper.

有人知道汇编中的fork错误返回值是什么吗?

Does anyone know what the fork error return value would be in assembly?

(我正在Linux上进行64位NASM组装)

(I'm doing 64 bit NASM assembly on Linux)

推荐答案

首先要注意的是,C库包装器

First and foremost note that the C library wrapper fork(2) invokes sys_clone and not sys_fork.

C库/内核差异

从2.3.3版开始,而不是调用内核的fork()系统.
调用,作为NPTL
的一部分提供的glibc fork()包装器 线程实现调用带有提供
的标志的clone(2) 与传统的系统调用具有相同的效果.

Since version 2.3.3, rather than invoking the kernel's fork() system
call, the glibc fork() wrapper that is provided as part of the NPTL
threading implementation invokes clone(2) with flags that provide the
same effect as the traditional system call.


Linux手册第2节简介解释了如何在一般情况下解释系统调用的返回值:


The introduction to the section 2 of the Linux manual explains how to interpret the return value of a system call in a general context:

返回值

发生错误时,大多数系统调用都会返回负错误号(即,
errno(3)中描述的常数之一的取反值. C
库包装程序向调用方隐藏了此详细信息:系统调用时
返回负值,包装器将绝对值复制到
errno变量,并返回-1
作为
的返回值 包装器.

On error, most system calls return a negative error number (i.e., the
negated value of one of the constants described in errno(3)). The C
library wrapper hides this detail from the caller: when a system call
returns a negative value, the wrapper copies the absolute value into
the errno variable, and returns -1
as the return value of the
wrapper.

因此,对于大多数 系统调用,EAX/RAX会在错误时保留-ESOMETHING,或者在成功时保留非负结果. libc包装器对此进行解码,以实现第2节手册中描述的errno设置和返回-1行为,这些手册主要记录了包装器;有时可以在Linux手册页的注释"部分中找到"C库/内核差异"的详细信息.

So for most system calls, EAX/RAX holds -ESOMETHING on error, or a non-negative result on success. The libc wrappers decode this to implement the errno-setting and returning -1 behaviour described in the section 2 man pages, which primarily document the wrappers; "C library/kernel differences" details are sometimes found in the Notes section of Linux man pages.

重要的是要注意,这适用于大多数但并非所有系统调用,如第一段所述.在这方面sys_fork并不特殊.如 errno(3) 更多内容mmap. (有效的指针可以设置高位,因此,将错误与成功区分开来还需要其他技巧,例如类似检查因为成功的mmap总是返回页面对齐地址,所以低位..)这些ABI详细信息未在手册页中记录.

It's important to note that this applies to most but not all system calls, as the first paragraph says. sys_fork is not special in this regard. A couple interesting special cases are getpriority as mentioned in the beginning of errno(3)more below, and mmap. (Valid pointers can have their high bit set, so distinguishing error from success requires other tricks, like checking the low bits since a successful mmap always returns a page-aligned address.) These ABI details are not documented in the man pages.

为了确定sys_fork调用是否成功,测试负值就足够了:

For the purpose of finding out if the sys_fork call was successful, testing for a negative value is enough:

test eax, eax
jl _error_handler              ;See Peter Cordes's comments below

我已经包括了有关C库包装的部分,例如 c2> ,因为它提供了一种实用的方法来找出错误号.
否定的errno值是系统调用可以返回的可能的错误值.

I've included the part about the C library wrappers like fork(2) because it gives a practical method to find out the error numbers.
The value of errno, negated, are the possible error values the system call can return.

EAGAIN
ENOMEM
ENOSYS
ERESTARTNOINTR

EAGAIN
ENOMEM
ENOSYS
ERESTARTNOINTR

通常,C库包装器可以在将返回值写入errno之前对其进行添加,删除或转码,因此这是失败的.

In general, the C library wrapper can add, remove or transcode the return values before writing them into errno, so this is failable.

找出可能的返回值的最终方法是查看源.
例如, do_fork sys_fork调用的,除了上面列出的值之外,还可以返回EINVALEPERM. 其他值也是可能的,我还没有深入研究所有嵌套函数调用.

The definitive way to find out the possible return values is looking at the source.
For example, do_fork, invoked by sys_fork, can return EINVAL and EPERM in addition to the values listed above.
Other values are possible, I haven't dug into all the nested function calls.

sys_clone也会调用do_fork,所以我认为 clone(2) 可以返回所有错误号fork(2)可以做到的.

sys_clone also invokes do_fork so I would assume that clone(2) can return all of the error numbers that fork(2) can.

调查 sys_getpriority 上面提到的评论出现了

Investigating the case of sys_getpriority mentioned above a comment came up

/*
 * Ugh. To avoid negative return values, "getpriority()" will
 * not return the normal nice-value, but a negated value that
 * has been offset by 20 (ie it returns 40..1 instead of -20..19)
 * to stay compatible.
 */

因此,看来Linux系统调用总是会在出错时返回负值,而C库包装程序则试图将这些值归一化为errno,这会引入额外的复杂性.

So it seems that Linux system calls always return negative values on an error, the C library wrappers than, in an attempt to normalise these values into errno, introduce an extra layer of complexity.

正如从mmap案例中看到的那样,设置符号位并不总是意味着它是一个错误值. 根据此答案 (值得在下面的Peter Cordes评论中找到),在 [-4095,-1] 范围内的值始终表示错误,而其他负值则不应.

As we see from the mmap case, having the sign bit set doesn't always mean it's an error value. According to this answer (merit goes to Peter Cordes comment below), values in the range [-4095, -1] always mean error, but other negative values should not.

这篇关于Fork系统调用失败后,rax中的返回值是多少?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆