Fork系统调用失败后,rax的返回值是多少?
我知道在C中调用fork()
将返回-1如果有错误,但我想知道当您在汇编中调用sys_fork
时返回值是什么。Fork系统调用失败后,rax的返回值是多少?
我通常可能会认为它也返回-1,但我已经处理了sys_brk,并且程序集中的原始系统调用返回了与C Brk()包装不同的东西。
有谁知道fork错误返回值将在汇编中?
(我做Linux上的64位NASM组装)
首先需要注意的是C库包装fork(2)
调用sys_clone
而不是sys_fork
。
C库/内核差异
由于2.3.3版本,而不是调用内核的fork()系统
呼叫,glibc的叉()包装,其作为NPTL的一部分提供
线程实现调用克隆(2)的标志提供了与传统系统调用相同的效果。
的introduction to the section 2 of the Linux manual说明了如何解释在一般情况下的系统调用的返回值:
返回值
上的错误,大多数系统调用返回负的错误编号(即,
否定了所述常数之一的值在errno(3))。与c
库包装隐藏来自呼叫者这一细节:当一个系统调用
返回负值,包装拷贝绝对值成
errno变量,并返回-1作为
的返回值 包装。
所以对于最系统调用,EAX/RAX持有-ESOMETHING
上的错误,或成功一个非负的结果。 libc包装器对此进行解码以实现在第2节手册页中描述的errno-setting和返回-1行为,主要记录包装器;有时会在Linux手册页的Notes部分找到“C库/内核差异”细节。
重要的是要注意,这适用于大多数系统调用,但不是所有的系统调用,如第一段所述。 sys_fork
在这方面并不特别。一对有趣的特殊情况是getpriority
,如errno(3)
开头所述,更多地低于和mmap
。 (有效指针可以设置其高位,因此区分错误与成功需要其他技巧,like checking the low bits since a successful mmap always returns a page-aligned address。)这些ABI细节未在手册页中记录。
对于找出如果sys_fork
调用成功的目的,测试负值是不够的:
test eax, eax
jl _error_handler ;See Peter Cordes's comments below
我已经包含对C库的包装像fork(2)
的一部分,因为它给出了找出错误数字的实用方法。
否定的errno
的值是系统调用可能返回的错误值。
EAGAIN
ENOMEM
ENOSYS
ERESTARTNOINTR
一般情况下,C库包装可以添加,删除或写入它们变成errno
之前转码的返回值,所以这是failable。
找出可能的返回值的确切方法是查看源代码。
例如,由sys_fork
调用的do_fork
除了上面列出的值之外,还可以返回EINVAL
和EPERM
。
其他值是可能的,我没有挖掘到所有的嵌套函数调用。
sys_clone
还援引do_fork
,所以我会假设, clone(2)
可以返回的所有错误数字,用于fork(2)
即可。
调查的评论上述sys_getpriority
的情况下想出了
/*
* 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
,引入额外的复杂层。
正如我们从mmap
的情况看到的那样,设置符号位并不总是意味着它是错误值。 根据this answer(优点参见下面的Peter Cordes评论),[-4095,-1]范围内的值总是表示错误,但其他负值不应该。
'test/jl'会比'test/js'更高效,因为它可以在Intel SnB系列上进行宏观融合。在比较零之后,行为是相同的,因为测试小于零与测试符号位相同。 –
你确定你需要测试完整的'rax',而不仅仅是'eax'吗? 'pid_t'是一个32位的类型,所以我认为在这里避免使用REX前缀是安全的。 (实际上,你确定返回值是符号扩展在所有出到64位?) –
@PeterCordes老实说,我不知道,我相信这个问题下的意见认为在最坏的PID应该签署扩展样句柄在Windows中。我会根据您的意见更正答案。谢谢! –
至少在ia32和x86_64中,IIRC通常是一个Linux系统调用,在失败时返回一个“errno”值的负值(然后glibc包装再次否定并存储到“errno”中)。 –
根据[x86_64](https://github.com/hjl-tools/x86-psABI/wiki/X86-psABI)ABI,返回值在'EAX'或'RAX'中。另请参阅[X86-64 ABI在哪里记录?](https://stackoverflow.com/q/18133812/608639) – jww
他知道根据ABI @jww,返回值在'RAX'中。这是在问题中说明的。问题是如何解释* RAX中的值。换句话说,这是什么意思? –