我知道,在C中调用fork()将返回-1,如果有错误,但我想知道当您在程序集中调用sys_fork时返回值是什么。
我通常可以假定它也返回-1,但是我已经处理了sys_brk和在程序集中的原始系统调用返回一些不同于C Brk()包装。
有谁知道在汇编中的fork错误返回值是什么?
(我在做Linux上的64位NASM程序集)
x86内存访问分段错误
无法理解下面的macros
如何在DOS中显示汇编中的字符?
试图了解主要拆卸的第一条指令
如何步debugging没有符号或部分的程序集二进制文件?
Linux内核中的UD2操作码的目的是什么?
不是07C0:0000,x86机器上的物理地址与0000:7C00相同吗?
Windows 7和Windows Server 2008 R2中不同的WinSxS行为
“呼叫0x80482f0 <puts @ plt>”? 只需要在x86汇编的“hello world”程序中澄清一行代码即可
首先要注意的是C库封装器fork(2)调用sys_clone而不是sys_clone 。
C库/内核差异
从版本2.3.3开始,而不是调用内核的fork()系统
调用,作为NPTL的一部分提供的glibc fork()包装器
线程实现调用克隆(2)与提供的标志
Linux手册第2部分的介绍解释了如何在一般情况下解释系统调用的返回值:
返回值
errno(3)中描述的常量之一的否定值)。 C
返回一个负值,包装器将该绝对值复制到
errno变量,并返回-1作为返回值
包装。
因此,对于大多数系统调用,EAX / RAX在出错时保存-ESOMETHING ,或者在成功时保持非负面结果。 libc包装器对此进行解码,以实现在第2节手册页中描述的errno-setting和返回-1行为,主要记录包装器; 有时会在Linux手册页的注释部分找到“C库/内核差异”细节。
重要的是要注意,这适用于大多数,但不是所有的系统调用,如第一段所述。 sys_fork在这方面不是特别的。 一些有趣的特例是errno(3)开头提到的getpriority和mmap 。 (有效指针可以设置高位,所以区分错误和成功需要其他技巧, 比如检查低位,因为成功的mmap总是返回一个页面对齐的地址 。)这些ABI细节没有记录在手册页中。
为了查明sys_fork调用是否成功,测试一个负值就足够了:
test eax,eax jl _error_handler ;See Peter Cordes's comments below
我已经包含了像fork(2)这样的C库包装器的部分,因为它提供了找出错误编号的实用方法。
EAGAIN
ENOMEM
ENOSYS
ERESTARTNOINTR
一般来说,C库封装器可以在将返回值写入errno之前添加,删除或转码返回值,因此这是失败的。
找出可能的返回值的确切方法是查看来源。
例如,除了上面列出的值外,由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案例中看到的那样,设置符号位并不总是意味着它是一个错误值。 根据这个答案 (下面的Peter Cordes评论的优点),范围[-4095,-1]中的值总是意味着错误,但是其他负值不应该。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。